クラスの初期化処理は Klass::initialize() で行われる. なお, このメソッドは各サブクラス(instanceKlass, objArrayKlass, typeArrayKlass) でオーバーライドされており, 実際にはサブクラスのメソッドが呼び出される.
初期化処理では, 以下の処理が行われる.
リンク処理の実行 (まだリンクされていない場合) (See: here for details)
スーパークラスの初期化処理の実行 (まだスーパークラスが初期化されていない場合)
static 初期化子 (=
Klass::initialize() (<= 実際にはこのメソッドの中身は必要なサブクラスでオーバーライドされている. オーバーライドされていないサブクラスについては呼ばれることはない)
-> * instanceKlass の場合:
-> instanceKlass::initialize()
-> instanceKlass::initialize_impl()
-> (1) (初期化前にリンクされていないとまずいので) リンクが終わった状態にしておく
-> instanceKlass::link_class()
-> (See: here for details)
(1) 他のスレッドが同時に初期化しようとしている可能性があるため, 排他を取る.
(他のスレッドが初期化中であればここで待機.
また, この時点で初期化されていたりあるいはエラーになっていれば, ここで終了)
(Java 仮想マシン仕様の "5.5 Initialization" における Step 1. ~ Step 6 の内容)
-> ObjectLocker::waitUninterruptibly() (※1)
-> instanceKlass::set_init_state()
-> instanceKlass::set_init_thread()
(1) スーパークラスの初期化が必要であれば, 先にスーパークラスを初期化する.
(Java 仮想マシン仕様の "5.5 Initialization" における Step 7. の内容)
-> instanceKlass::initialize() (super に対して再帰呼び出し)
(1) 対象クラスを初期化する (= <clinit> メソッドを呼び出す)
(Java 仮想マシン仕様の "5.5 Initialization" における Step 9. の内容)
-> instanceKlass::call_class_initializer()
-> instanceKlass::call_class_initializer_impl()
-> instanceKlass::class_initializer()
-> JavaCalls::call()
-> (See: here for details)
(1) もし初期化処理が正常に終了した場合は, 排他を解除して終了
(Java 仮想マシン仕様の "5.5 Initialization" における Step 10. の内容)
-> instanceKlass::set_initialization_state_and_notify()
-> instanceKlass::set_initialization_state_and_notify_impl()
-> instanceKlass::set_init_state()
-> ObjectLocker::notifyAll() (※1で待機しているスレッドを起こす)
(1) もし初期化処理で例外が出ていれば, 排他を解除した後, 例外を投げ直す
(Java 仮想マシン仕様の "5.5 Initialization" における Step 11. 及び Step 12. の内容)
-> instanceKlass::set_initialization_state_and_notify()
-> (同上)
-> THROW_OOP() or THROW_ARG()
* objArrayKlass の場合:
-> objArrayKlass::initialize()
-> instanceKlass::initialize() or typeArrayKlass::initialize()
* typeArrayKlass の場合:
-> typeArrayKlass::initialize()
-> (何もしない)
* その他の場合(オーバーライドされていない場合)
-> Klass::initialize()
-> ShouldNotReachHere()
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details (#Note #ifdef ASSERT 時には少し違うバージョンが定義されている)
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.