7

小さな問題があります。私はJavaSEを学び、クラスClassLoaderを見つけました。以下のコードで使用しようとしています。URLClassLoaderを使用して、実行時にクラスを動的にロードしようとしています。

URLClassLoader urlcl = new URLClassLoader(new URL[] {new URL("file:///I:/Studia/PW/Sem6/_repozytorium/workspace/Test/testJavaLoader.jar")});
Class<?> classS = urlcl.loadClass("michal.collection.Stack");
for(Method field: classS.getMethods()) {
     System.out.println(field.getName());
}
Object object = classS.newInstance();
michal.collection.Stack new_name = (michal.collection.Stack) object;

Java仮想マシンはクラスを認識せず、次の例外が発生します。

Exception in thread "main" java.lang.Error: Unresolved compilation problems: michal cannot be resolved to a type michal cannot be resolved to a type at Main.main(Main.java:62)

私がこの問題を解決する方法を知っていますか?

4

3 に答える 3

3
Class<?> classS = urlcl.loadClass("michal.collection.Stack");
[...]
Object object = classS.newInstance();
michal.collection.Stack new_name = (michal.collection.Stack) object;

したがって、クラスを動的にロードしようとしてから、静的に参照します。すでに静的にリンクできる場合は、ロードされており、再度ロードすることはできません。リフレクションによってメソッドにアクセスする必要があります。

通常は、ロードされたクラスに親クラスローダーからのインターフェイスを実装させます。インスタンスが作成された後(通常は単一のインスタンスのみ)、インターフェイスのタイプを使用した参照を通じてインスタンスを参照できます。

public interface Stack {
   [...]
}
[...]
    URLClassLoader urlcl = URLClassLoader.newInstance(new URL[] {
       new URL(
           "file:///I:/Studia/PW/Sem6/_repozytorium/workspace/Test/testJavaLoader.jar"
       )
    });
    Class<?> clazz = urlcl.loadClass("michal.collection.StackImpl");
    Class<? extends Stack> stackClass = clazz.asSubclass(Stack.class);
    Constructor<? extends Stack> ctor = stackClass.getConstructor();
    Stack stack = ctor.newInstance();

(通常のStack Overflowの免責事項は、コンパイルほどではありません。)

好みに合わせてエラー処理を追加する必要があります。URLClassLoader.newInstanceに少し洗練を加えますURLClassLoaderClass.newInstance例外処理が完全に壊れているため、回避する必要があります。

于 2012-03-13T21:03:53.943 に答える
3

上記の答えはどちらも間違っています。根本的な問題を理解していません。メインは、1 つのクラス ローダーによってロードされた Stack クラスを参照します。urlclassloader が同じ名前のクラスをロードしようとしています。これらは同じではなく、異なるクラスローダーに属しているため、ロードされたものを参照されたものにキャストすることはできません。それぞれの has コードを印刷して、それらが異なることを確認できます。同等性テストでも、cclass 参照が異なることが示されます。あなたの問題はおそらく、sstack によって参照される依存クラスが見つかる可能性があるためNoClassDefErrorsです。

于 2012-03-15T11:08:32.553 に答える
0

You can't refer to the dynamically-loaded type by name in the code, since that has to be resolved at compile-time. You'll need to use the newInstance() function of the Class object you get back from loadClass().

于 2012-03-13T21:02:02.577 に答える