非常に一般的なコードがあります: System.out.println。これは非常に一般的な出力ステートメントですが、しばらく勉強した後、突然ソース コードを見ることを思い出しました。以下はソース コードです:
リーリーout は System クラスの下で定義されており、インスタンス化されていません。Out は単なる null 変数であり、静的オブジェクトを呼び出すことさえできません。ただし、PrintStream クラスの下で println() メソッドを呼び出すことはできます。これは問題ではありません。理解?どういうことなんですか?
詳しい説明: 中国語版 http://www.cnblogs.com/skywan...
jdk7 ベースの英語版 https://luckytoilet.wordpress...
まず第一に、テスト クラスを開始するとき、つまりテスト クラスをインスタンス化するとき、呼び出すすべての静的クラスが最初にインスタンス化されるため、実際に System.out.println ステートメントを実行すると、 System クラスのメソッドとプロパティが初期化されました。
静的{
リーリー}
上記の静的メソッドのアノテーションは、初期化のために initializeSystemClass メソッドが呼び出されることを示しています。このメソッドの setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding")));出力するには、
private staticative void setOut0(PrintStream out) はネイティブ メソッドです。
final static を見たとき、私の最初の反応は、これは定数であり、定数は初期化する必要があるということでした。そして、再度それを探しました。そして、案の定、初期化するためにローカル メソッドを呼び出しています。
initializeSystemClass() 関数で行われる初期化作業は、システム スレッドが初期化された後に呼び出されます。つまり、すべての静的メンバー変数 (err out in) がこの関数で初期化されます。
たとえば、この out:
FileOutputStream。 fdOut = new FileOutputStream(FileDescriptor.out);
setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding")));
setOut0() 関数はネイティブ層にあり、初期化されたファイル間の接続を確立します。オブジェクトとこれをネイティブレイヤーに出力します