我正在尝试使用反射来获取实现抽象类Detector
的类列表。我想使用此列表的元素(类型为Class<T extends Detector>
)作为另一个类DetectorWrapper<T extends Detector>
的类型参数,以便我可以轻松地在该类中实例化T
(即,使用new T(...)
)。是否可以为此使用反射,或者我应该将Class<T>
传递给DetectorWrapper
并在我需要T
的实例时使用反射来调用构造函数?
答案 0 :(得分:1)
没有办法使用Class
对象作为类型参数,但这无关紧要,因为类型参数正是你无论如何都无法实例化的,即你不能说{{1 }}
因此,您需要一个new T()
对象来实例化该类型的对象,并可以定义与type参数的关系:
Class
虽然对于大多数实际问题,class DetectorWrapper<T extends Detector> {
final List<T> detectors;
DetectorWrapper(Class<? extends T>... types) {
ArrayList<T> result=new ArrayList<>(types.length);
try {
for(Class<? extends T> type: types) result.add(type.newInstance());
}catch(InstantiationException|IllegalAccessException ex) {
throw new IllegalArgumentException(ex);
}
this.detectors=result;
}
}
类的类型参数已过时,即您可以使用
DetectorWrapper
有像
这样的课程 class DetectorWrapper {
final List<Detector> detectors;
DetectorWrapper(Class<? extends Detector>... types) {
ArrayList<Detector> result=new ArrayList<>(types.length);
try {
for(Class<? extends Detector> type: types) result.add(type.newInstance());
}catch(InstantiationException|IllegalAccessException ex) {
throw new IllegalArgumentException(ex);
}
this.detectors=result;
}
}
您可以通过class Detector {}
class Foo extends Detector {}
class Bar extends Detector {}
实例化DetectorWrapper
。
请注意new DetectorWrapper(Foo.class, Bar.class)
假定为无参数构造函数。如果您知道常见的构造函数签名,则可以使用Class.newInstance()
。
使用Java 8,有一个更强大,非反射的选择:
type.getConstructor(parameterTypes).newInstance(initargs);
可以像class DetectorWrapper {
final List<Detector> detectors;
DetectorWrapper(Supplier<? extends Detector>... types) {
ArrayList<Detector> result=new ArrayList<>(types.length);
for(Supplier<? extends Detector> s: types) result.add(s.get());
this.detectors=result;
}
}
一样进行实例化,假设设置与上面相同。
等效的替代实施方案是:
new DetectorWrapper(Foo::new, Bar::new)
但是如果你在运行时动态发现class DetectorWrapper {
final List<Detector> detectors;
DetectorWrapper(Supplier<? extends Detector>... types) {
detectors=Arrays.stream(types).map(Supplier::get).collect(Collectors.toList());
}
}
个对象,就无法进行反射实例化。