使用Reflections创建新的类实例

时间:2013-03-03 18:48:38

标签: java reflection

我正在尝试使用https://code.google.com/p/reflections/

找到的反射库

我想要实现的是扫描项目中的包,然后创建在该包中找到的给定类型的所有子类的实例。 我正在使用该库的方式是正确的,因为subTypes返回以下内容:

  

[class identifiers.DNSLookup,class identifiers.AliasChecker,class   identifiers.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)

作为最后一点,是否可以使用上述功能根据其界面而不是超类来扫描类?感谢。

3 个答案:

答案 0 :(得分:3)

在您的代码中:

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

此处detectorClass<? extends DetectorSub>

的实例

然后:

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

您正在getClass()上调用detector,即您在Class<? extends DetectorSub>实例上调用getClass()并获得代表Class的类对象,而不是子类型DetectorSub了。因此,当您创建新实例时,实际上是在尝试创建Class的新实例,该实例失败,因为Class的默认构造函数是私有的。

你应该写:

DetectorSub d = detector.newInstance();

答案 1 :(得分:1)

你的意思是?

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

// or DetectorSub d = (DetectorSub) detector.newInstance();
// since it invokes the no-args constructor

答案 2 :(得分:0)

在线

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

无需再次致电getClass()。它应该只是:

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