以下是一个假设问题。我纯粹感兴趣的是,效果是否可以通过任何可以想象的模糊手段(不安全的API、JNI、ASM等(实现。这不是XY问题,我从来没有计划写这样的代码!我只是好奇里面的东西
让我们假设我们在Java中有一个非常简单的层次结构:
class Cupcake {
public String kind;
// ...
}
class WholeRealityItself extends Cupcake {
public Object[] wholeMatterOfUniverse;
// transform internal state because reasons
public performBigBangAndFluctuateACupcake() {
// ... chaotic spacetime fluctuations produce a cupcake
this.kind = "quantum_with_sprinkles";
}
}
我们的流程如下:
WholeRealityItself reality = new WholeRealityItself();
reality.performBigBangAndFluctuateACupcake();
Cupcake cupcake = (Cupcake) reality; // upcast
// from now on the object will be only accessed via it's supertype and never downcast
用文字表达:
- 我们创建了一个subtype的对象,该对象分配了大量内存
- 我们对此子类型对象执行一些内部状态转换
- 我们将对象上转换为它的超类型,从现在起,我们将只通过它的超型引用它,而从不下转换
因此,现在我们的JVM拥有一个对内部WholeRealityItself
对象的Cupcake
引用,该对象的内存(程序员知道(将永远不会被访问。是的,我知道引用和实际分配的对象是两种不同的东西,上转换/下转换使程序只是";重新解释";一个物体。
完全忽略了这样一个事实,即这种令人厌恶的代码是不可用的,应该用一个理智的构建器/工厂/副本或其他什么来代替,只是为了论证起见,假设我们希望它是这样的重点不是如何达到同样的效果,而是如果以下情况可能的话:。
是否可以强制缩小实际分配的OBJECT,以将其内部从WholeRealityItself
隐藏到Cupcake
,并强制解除分配wholeMatterOfUniverse
AKA-你能SOMEHOW切片一个底层分配的OBJECT吗?关于对象切片的最后一个问题是大约10年前的问题。
AKA-您能用某种方法对底层分配的OBJECT进行切片吗?
不,你不能。
对象由堆节点表示。如果您做了任何干扰堆节点的大小或类型(类(的事情,那么很可能会导致垃圾收集器崩溃。
我想,您可以使用打破抽象(讨厌!(的反射来识别null
,并将其分配给子类添加的所有字段。但问题是,您不能对子类重载的超类的方法采取任何措施。如果这些方法引用了您已将null
分配给的任何字段,并且something调用了它们,那么您就有一个潜在的已损坏(已损坏(对象。
我的建议是:使用WholeRealityItself
对象的相关状态创建一个全新的Cupcake
对象。它将有一个不同的参考。处理好这个。
David Wheeler的报价可能与。。。
"计算机科学中的所有问题都可以通过另一种间接方法来解决">
上转换和下转换都不会改变对象本身——它们只会影响编译器如何处理对对象的引用。
一个例子是overriden方法:调用什么方法完全取决于对象的运行时类型,而不是编译器使用的引用类型:
class Cupcake {
public String kind;
// ...
public void printMeOut() {
System.out.println("Cupcake");
}
}
class WholeRealityItself extends Cupcake {
public Object[] wholeMatterOfUniverse;
@Override
public void printMeOut() {
System.out.println("WholeRealityItself");
}
public performBigBangAndFluctuateACupcake() {
//...
}
}
在您的样本代码之后
WholeRealityItself reality = new WholeRealityItself();
reality.performBigBangAndFluctuateACupcake();
Cupcake cupcake = (Cupcake) reality; // upcast
// from now on the object will be only accessed via it's supertype and never downcast
呼叫CCD_ 10将打印出";整体真实性;现在每一次都很重要,自从上次播出以来已经过去了多少时间。
您正在讨论向上广播,但您的对象没有发生任何变化。释放的唯一方法是在cubecake中有一个构造函数,该构造函数将接受另一个cubecke作为输入,并且只使用所需的部分。之后你会释放整个世界。