Reputation: 442
The following is a hypothetical problem. I'm purely interested if the effect is SOMEHOW achievable, by any obscure means imaginable (unsafe API, JNI, ASM etc). It is not an XY problem and I don't ever plan to write code like that! I'm just curious about internals.
Let's assume that we have this very simple hierarchy in 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";
}
}
Our process is as follows:
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
Putting it into words:
So now our JVM holds a Cupcake
reference to an internal WholeRealityItself
object with memory that (the programmer knows) will never again be accessed. Yes, I know that references and actual allocated objects are two different things and upcasts/downcasts make the program just "reinterpret" an object.
Completely ignoring the fact that this abomination of a code is unusable and should be replaced with a sane builder/factory/copy or whatever, just assume for the sake of argument that we want it that way. The point is not how to achieve the same effect but if the following is possible:.
Can you force a narrowing of the actual allocated OBJECT to covert it's internals to a Cupcake
from WholeRealityItself
and force deallocation of wholeMatterOfUniverse
?
AKA - can you SOMEHOW slice an underlying allocated OBJECT? Last questions about object slicing are from ~10 years ago.
Upvotes: 1
Views: 114
Reputation: 719336
AKA - can you SOMEHOW slice an underlying allocated OBJECT?
No you can't.
The object is represented by a heap node. If you did anything to interfere with the size or type (class) of the heap node, you are liable to crash the garbage collector.
I guess, you could use abstraction breaking (nasty!) reflection to identify and assign null
to all of the fields added by the subclass. But the problem is that you can't do anything about methods of the superclass that the subclass has overloaded. If those methods refer to any of the fields that you have assigned null
to, and something calls them, you have a potentially broken (smashed) object.
My advice: create a brand new Cupcake
object using the relevant state from your WholeRealityItself
object. It will have a different reference. Deal with that.
This David Wheeler quotation may be relevant ...
"All problems in computer science can be solved by another level of indirection."
Upvotes: 3
Reputation: 21610
Neither upcasts nor downcasts change the object itself - they only influence how the compiler treats the reference to the object.
One example are overriden methods: what method is called depends entirely on the runtime type of the object, not on the reference type that the compiler uses:
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() {
//...
}
}
After your sample code
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
the call cupcake.printMeOut();
will print out "WholeRealityItself" every time now matter how much time passed since the upcast.
Upvotes: 1
Reputation: 1723
You are talking about upcasting and nothing happens to your object. Only way to free would be to have a constructor in cupecake that would take another cupecake as input and would only use the needed parts. After you would release wholeworld.
Upvotes: 0