JVM のベリファイアが起動してクラスをチェックする正確な状況を知りたいです。そのようなインスタンスの 1 つは、クラスをロードするときであることは知っていますが、クラスがロードされ、後で検証されることがあります。だからこそ、それがいつ起こるかを正確に知りたいのです。
1 に答える
仕様 (§4.10) には次のように記載されています。
Java 仮想マシンの実装は、リンク時に各クラス ファイルが必要な制約を満たしていることを確認します (§5.4)。
§5.4 では、「リンク時間」が正確に何を意味するかを定義しています。
クラスまたはインターフェースのリンクには、必要に応じて、そのクラスまたはインターフェース、その直接のスーパークラス、その直接のスーパーインターフェース、およびその要素の型 (配列型の場合) の検証と準備が含まれます。クラスまたはインターフェースでのシンボリック参照の解決は、リンクのオプション部分です。
この仕様により、次のすべてのプロパティが維持されている場合、アクティビティのリンク (および再帰のため、読み込み) がいつ行われるかに関して実装の柔軟性が得られます。
A class or interface is completely loaded before it is linked. A class or interface is completely verified and prepared before it is initialized. Errors detected during linkage are thrown at a point in the program where some action is taken by the program that might, directly
または間接的に、エラーに関係するクラスまたはインターフェイスへのリンケージが必要です。
たとえば、Java 仮想マシンの実装では、クラスまたはインターフェースの各シンボリック参照を、使用時に個別に解決するか (「遅延」または「遅延」解決)、またはクラスの検証時にすべてを一度に解決するか (「レイジー」または「レイト」解決) を選択できます。 「熱心な」または「静的な」解決)。これは、一部の実装では、クラスまたはインターフェースが初期化された後、解決プロセスが続行される可能性があることを意味します。どちらの戦略に従うにしても、解決中に検出されたエラーは、クラスまたはインターフェイスへのシンボリック参照を (直接的または間接的に) 使用するプログラム内のポイントでスローする必要があります。
実際のところ、少なくとも Hotspot は説明されているように遅延初期化を行っていることに注意してください (JRockit と共同作業者が別の方法で行っていたとしたら、非常に驚かれることでしょう)。
ソース:
http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.10
http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html#jvms-5.4