0

JLS Chapter 12. Executionを読んだので、解決について書かれています

解決とは、言及されている他のクラスおよびインターフェースをロードし、参照が正しいことを確認することによって、Test から他のクラスおよびインターフェースへのシンボリック参照をチェックするプロセスです。

解決ステップは、初期リンク時のオプションです。実装は、非常に早い段階でリンクされているクラスまたはインターフェースからのシンボリック参照を解決する場合があり、さらに再帰的に参照されるクラスおよびインターフェースからのすべてのシンボリック参照を解決する場合もあります。...

実装は、代わりに、シンボリック参照がアクティブに使用されている場合にのみ、シンボリック参照を解決することを選択できます。すべてのシンボリック参照に対してこの戦略を一貫して使用すると、解決の「最も怠惰な」形式になります。この場合、Test が別のクラスへのシンボリック参照を複数持っていた場合、これらの参照がプログラムの実行中に使用されなかった場合、参照は一度に 1 つずつ解決されるか、まったく解決されない可能性があります。

たとえば、実装では、クラスまたはインターフェイス内の各シンボリック参照を、それが使用されている場合にのみ個別に解決するか (遅延解決または遅延解決)、またはクラスの検証中にすべてを一度に解決するか (静的解決) を選択できます。これは、一部の実装では、クラスまたはインターフェースが初期化された後、解決プロセスが続行される可能性があることを意味します。

私の質問は、遅延初期化の使用を選択/強制することを選択できるかどうかです。たぶん、カスタム クラス ローダーを作成する必要がありますか? または、起動時のクラスローダーの ClassNotFoundException が無視される可能性がありますか?

main実際に発生してはならないオブジェクトの条件付き作成があり、対応するクラスがjarにありません。ただし、実行を開始するNoClassDefFound前でもスローされます。main

4

3 に答える 3

2

NoClassDefFoundErrorエラー:

Java 仮想マシンまたはClassLoaderインスタンスが (通常のメソッド呼び出しの一部として、または式を使用した新しいインスタンスの作成の一部として) クラスの定義にロードしようとしたときに、クラスnewの定義が見つからなかった場合にスローされます。

問題のクラスのインスタンスのインスタンス化に関連しないエラー。あなたの例では、「外部」クラスがそのタイプのフィールドを定義していれば、それで十分かもしれません。メインを含むクラスは、実行時にクラスパスで使用できないタイプに依存しているため、ロードできません。

疑わしい場合は、インポート ステートメントを調べて、動的にロードするクラスの import * ) を削除してください。次に、そのクラスのインポートを再度追加せずに、エラー マーカーを削除してみてください。

* ) - この動的にロードされたクラスは別のパッケージにあり、それをインポートする必要があると思います。

于 2012-12-18T09:13:55.380 に答える
2

Oracle の JVM ではできません。

ドキュメントによると、クラスローダーはクラスのロードを延期できません。また、リンクの順序とタイミングは実装固有です。私の知る限り、ほとんどの JVM はできるだけ早くリンクすることを選択し、一部はコンパイル時にもリンクします (この例については、Excelsior JET を参照してください)。

于 2012-12-18T09:15:56.110 に答える
1

このことを考慮

class Test2 {
}

public class Test1 {
    static Test2 test2;

    public static void main(String[] args) {
        System.out.println("Test1");
        test2 = new Test2();
    }
}

私はそれをコンパイルし、Test2.classを削除してjava -cp . Test1出力を実行しました

    Test1
    Exception in thread "main" java.lang.NoClassDefFoundError: Test2
        at Test1.main(Test1.java:9)
    Caused by: java.lang.ClassNotFoundException: Test2
        at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
......

私の見解では、これは、JVM の依存関係の解決がデフォルトで遅延していることを意味します。JVM は、Test2.class が最初に使用されるまで欠落していることに気付きませんでした。

于 2012-12-18T09:33:12.727 に答える