ネイティブ・イメージのクラスの初期化

Javaのセマンティクスにより、実行時にクラスに初めてアクセスが発生したときにそのクラスを初期化することが求められます。クラスの初期化は、JavaのAhead-of-Timeコンパイルに対して、次のような悪影響を及ぼします:

クラスの初期化による悪影響を軽減するために、ネイティブ・イメージではビルド時におけるクラスの初期化がサポートされています。イメージのビルド中に特定のクラスを初期化して、実行時の初期化とチェックを不要にすることができます。初期化されたクラスのすべての静的状態情報がイメージに格納されます。ビルド時に初期化された静的フィールドへのアクセスは、アプリケーションに対して透過的であり、クラスが実行時に初期化されたかのように機能します。

クラス初期化ポリシーの指定は、クラス初期化セマンティクスに起因する次の制約のために複雑になる場合があります:

ネイティブ・イメージの操作性はそのまま保ちながらビルド時の初期化のメリットを得るために、ネイティブ・イメージでは次の3つのことが行われます:

初期化されたクラスとその理由を追跡するには、フラグ-H:+PrintClassInitializationを使用します。このフラグは、イメージ・ビルドが意図したとおりに動作するように構成するために非常に役立ちます。目的は、プログラムの正しいセマンティクスを維持したまま、可能なかぎり多くのクラスをビルド時に初期化することです。

ネイティブ・イメージ・ランタイムのビルド時の初期化

ネイティブ・イメージ・ランタイムでは、ほとんどのクラスがイメージのビルド時に初期化されます。これには、ガベージ・コレクタ、重要なJDKクラス、デオプティマイザなどが含まれます。ネイティブ・イメージでは、ビルド時に初期化されるランタイム内のすべてのクラスを適切にサポートするために、ビルド時に初期化が発生してもセマンティクスは維持されるようになっています。ビルド時のクラスの初期化が原因でJDKクラスが正しく動作しない場合は、問題を報告してください。

安全なクラスの自動初期化

アプリケーション・クラスについては、ネイティブ・イメージにより、ビルド時に安全に初期化できるクラスの検出が試みられます。クラスは、そのすべての関連スーパータイプが安全で、かつ、クラス・イニシャライザが安全でないメソッドをコールすることや、他の安全でないクラスを初期化することがない場合、安全とみなされます。

メソッドは次の場合に安全でないとみなされます:

安全であると実証されているクラスの例を示すテストは、ここで参照できます。コマンドラインで-H:+PrintClassInitializationを設定すると、安全であると実証されているすべてのクラスのリストがファイルに表示されます。

クラスの初期化の明示的な指定

各クラスは実行時(1)に初期化することも、ビルド時(2)に初期化することもできます。クラス初期化ポリシーを指定するために、--initialize-at-build-time--initialize-at-run-timeの2つのフラグが用意されています。これらのフラグを使用すると、パッケージ全体または個々のクラスのポリシーを指定できます。たとえば、クラスp.C1p.C2、...またはp.Cnがある場合、次のようにしてこのパッケージを即時に初期化できます:

--initialize-at-build-time=p

パッケージp内のクラスのいずれかを遅延させる場合は、単に、次の内容を追加します:

--initialize-at-run-time=p.C1

クラス階層全体をビルド時に初期化するには、コマンドラインで--initialize-at-build-timeを渡します。

ネイティブ・イメージ機能RuntimeClassInitializationを使用して、プログラムでクラスの初期化を指定することもできます。