再帰的にネストされたクラス

Javaのネストされたクラスの興味深い機能を見つけました-再帰的に無限にネストできます!



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(); } } 


Testクラスの両方のインスタンスが、それらを含むMainクラスを参照することを期待できます。 ただし、コンパイルして実行すると、興味深い画像が得られます

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



つまり、最後の2つのインスタンスのMain.thisはMain $ Test型であり、インスタンス自体は相互に参照し、チェーン状に並んでいます!

この機能は、LinkedListのより効率的な実装のアイデアを提起します。 JVMが外側のクラスへのリンクを保存している場合、それは興味深いものです。 リンクが暗黙的にネストされたクラスの追加フィールドである場合、メモリは同じになります。 しかし、このリンクのメモリがすべてのクラスのために予約されている場合、要素ごとに余分な8バイトのゲームはろうそくの価値があります:)

UPD:最初のオプションに従ってすべてが解決されることがわかります-コンパイラは合成フィールドを導入します。 そのため、勝利は機能しません-LinkedList.Nodeで使用されるリンクは単純に合成されます

Source: https://habr.com/ru/post/J126928/


All Articles