
Recursively nested classes
I just stumbled upon an interesting feature of nested classes in Java - they can be nested recursively and endlessly!
You can expect both instances of the Test class to reference the Main class that includes them. However, if you compile and run, you get an interesting picture. That is, Main.this in the last two instances is of type Main $ Test, and the instances themselves refer to each other, lining up in a chain! This feature raises the idea of a more efficient implementation of LinkedList. It's just interesting where the JVM stores a link to the enclosing class. If the link is implicitly an additional field of the nested class, then the implementations will be the same in memory. But if the memory for this link is reserved for all classes, then the game for the extra eight bytes per element is worth the candle :)
UPD: it turns out everything is solved according to the first option - the compiler introduces synthetic fields. So you won’t win - the link used by LinkedList.Node will simply be synthetic
public class Main {
private Main() {}
class Test extends Main {
{
System.out.printf("This: %h\nEnclosed in: %h\n", this, Main.this);
System.out.printf("Main.this is instance of %s\n\n" , Main.this.getClass());
}
}
public static strictfp void main(String... args) {
new Main().new Test().new Test().new Test();
}
}
You can expect both instances of the Test class to reference the Main class that includes them. However, if you compile and run, you get an interesting picture. That is, Main.this in the last two instances is of type Main $ Test, and the instances themselves refer to each other, lining up in a chain! This feature raises the idea of a more efficient implementation of LinkedList. It's just interesting where the JVM stores a link to the enclosing class. If the link is implicitly an additional field of the nested class, then the implementations will be the same in memory. But if the memory for this link is reserved for all classes, then the game for the extra eight bytes per element is worth the candle :)
This: 6665e41
Enclosed in: 2ab600af
Main.this is instance of class Main
This: 796686c8
Enclosed in: 6665e41
Main.this is instance of class Main$Test
This: 3a1af2bc
Enclosed in: 796686c8
Main.this is instance of class Main$Test
UPD: it turns out everything is solved according to the first option - the compiler introduces synthetic fields. So you won’t win - the link used by LinkedList.Node will simply be synthetic