I'm trying to use reflection to get a list of classes implementing an abstract class, Detector
. I would like to use the elements of this list (of type Class<T extends Detector>
) as a type parameter for another class, DetectorWrapper<T extends Detector>
, so that I can easily instantiate T
within that class (i.e., using new T(...)
). Is it possible to use reflection for this, or should I instead pass Class<T>
to DetectorWrapper
and use reflection to invoke the constructor whenever I need an instance of T
?

- 848
- 6
- 15
-
This question is not a duplicate of the linked question. I found those solutions in my search, but they do the exact **opposite** of what I want. In the linked question, the type `T` is retrieved. I do not want to query the type of a given reflected parameterized type, but rather I want to use a reflected type as a type parameter. I'm not sure how to improve the question to clarify this. – Rens van der Heijden Jun 01 '16 at 18:46
1 Answers
There is no way to use a Class
object as a type parameter, but that doesn’t matter, as a type parameter is exactly what you can never instantiate anyway, i.e. you can’t say new T()
.
So you need a Class
object to instantiate an object of that type and may define a relationship to the type parameter:
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;
}
}
Though for most practical issues, the type parameter of the DetectorWrapper
class is obsolete, i.e. you may use
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;
}
}
Having classes like
class Detector {}
class Foo extends Detector {}
class Bar extends Detector {}
you can instantiate a DetectorWrapper
via new DetectorWrapper(Foo.class, Bar.class)
.
Note that Class.newInstance()
assumes a no-arg constructor. You may use type.getConstructor(parameterTypes).newInstance(initargs);
instead, in case you know a common constructor signature.
With Java 8, there is a more robust, non-reflective alternative:
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;
}
}
which can be instantiated like new DetectorWrapper(Foo::new, Bar::new)
, assuming the same setup as above.
An equivalent alternative implementation would be:
class DetectorWrapper {
final List<Detector> detectors;
DetectorWrapper(Supplier<? extends Detector>... types) {
detectors=Arrays.stream(types).map(Supplier::get).collect(Collectors.toList());
}
}
But if you discover the Class
objects dynamically at runtime, there is no way around the reflective instantiation.

- 285,553
- 42
- 434
- 765
-
Oddly enough, `new T()` seemed to compile fine once I specified `
`, but I can see now why it is a bad idea. I was also using `T` to call some static methods that I defined on `Detector`, which was my additional motivation for this use case. Thanks for the extensive answer, especially the non-reflective example! – Rens van der Heijden Jun 02 '16 at 14:30 -
1`new T()` can’t work if `T` is referring to a type parameter. There’s possibly a different `T` in scope or another misunderstanding. Using `T.method` to invoke a `static` method of `Detector` has no benefit (if you think that `T` is less to type compared to `Detector`, consider `import static`. By the way, I forgot to add `@SafeVarargs` to the constructors, you really want to do that in production code… – Holger Jun 02 '16 at 14:40