使用Class <t>实例作为类型参数

时间:2016-06-01 15:04:47

标签: java reflection

我正在尝试使用反射来获取实现抽象类Detector的类列表。我想使用此列表的元素(类型为Class<T extends Detector>)作为另一个类DetectorWrapper<T extends Detector>的类型参数,以便我可以轻松地在该类中实例化T(即,使用new T(...))。是否可以为此使用反射,或者我应该将Class<T>传递给DetectorWrapper并在我需要T的实例时使用反射来调用构造函数?

1 个答案:

答案 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()); } } 个对象,就无法进行反射实例化。