2

https://code.google.com/p/reflections/にある反射ライブラリを試しています。

私が達成しようとしているのは、プロジェクト内のパッケージをスキャンし、そのパッケージ内にある特定のタイプのすべてのサブクラスのインスタンスを作成することです。subTypes が次を返すため、ライブラリの使用方法は正しいです。

[クラス識別子.DNSLookup、クラス識別子.AliasChecker、クラス識別子.GoogleSafeBrowsing]

私の問題は、そのセット内にあるクラスの新しいインスタンスを作成する方法です。それらはすべて、引数のないコンストラクターを持っています。

private void getDetectors(){
        Reflections reflections = new Reflections("identifiers"); //name of package to scan

        Set<Class<? extends DetectorSub>> subTypes =
                reflections.getSubTypesOf(DetectorSub.class);
        System.out.println(subTypes); // correct classes included here.
        for(Class<? extends DetectorSub> detector:subTypes){
            try {
                DetectorSub d =(DetectorSub)detector.getClass().newInstance().cast(DetectorSub.class); //returns exceptions at runtime.
            } catch (InstantiationException e) {
                e.printStackTrace();  
            } catch (IllegalAccessException e) {
                e.printStackTrace();  
            }
        }
    }

上記のコードは、次の例外を返します。

java.lang.IllegalAccessException: Can not call newInstance() on the Class for java.lang.Class
    at java.lang.Class.newInstance0(Class.java:339)
    at java.lang.Class.newInstance(Class.java:327)
    at core.PhishingScanner.getDetectors(PhishingScanner.java:40)
    at core.PhishingScanner.<init>(PhishingScanner.java:28)
    at core.Main.main(Main.java:13)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

最後に、上記の機能を使用して、スーパークラスではなくインターフェイスに基づいてクラスをスキャンすることは可能ですか? ありがとう。

4

3 に答える 3

3

あなたのコードで:

for(Class<? extends DetectorSub> detector:subTypes){

ここdetectorにの例がありますClass<? extends DetectorSub>

その後:

DetectorSub d =(DetectorSub)detector.getClass().newInstance().cast(DetectorSub.class);

を呼び出しgetClass()detectorいます。つまり、インスタンスで getClass() を呼び出しており、サブタイプではなく、Class<? extends DetectorSub>それを表すクラス オブジェクトを取得します。したがって、新しいインスタンスを作成するときは、実際には の新しいインスタンスを作成しようとしていますが、 のデフォルトのコンストラクターがプライベートであるため失敗します。ClassDetectorSubClassClass

代わりに次のように書く必要があります。

DetectorSub d = detector.newInstance();
于 2013-03-03T18:53:08.817 に答える
1

ということですか?

DetectorSub d = (DetectorSub) detector.getDeclaredConstructors()[0].newInstance();

// or DetectorSub d = (DetectorSub) detector.newInstance();
// since it invokes the no-args constructor
于 2013-03-03T18:52:09.440 に答える
0

オンライン

DetectorSub d =(DetectorSub)detector.getClass().newInstance().cast(DetectorSub.class);

再度電話する必要はありませんgetClass()。それはただあるべきです:

DetectorSub d =(DetectorSub)detector.newInstance().cast(DetectorSub.class);
于 2013-03-03T18:52:52.180 に答える