我正在尝试使用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)
作为最后一点,是否可以使用上述功能根据其界面而不是超类来扫描类?感谢。
答案 0 :(得分:3)
在您的代码中:
for(Class<? extends DetectorSub> detector:subTypes){
此处detector
是Class<? 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);