Reputation: 4956
I have following class:
public class Publisher<T> {
private static final Class[] SUPPORTED_CLASSES = new Class[]{T1.class, T2.class};
public Publisher() {
if(Arrays.asList(SUPPORTED_CLASSES).contains(T)) { // error: expression expected!
System.out.println("Class not supported!");
}
}
}
How can I check if class parameter conforms to the implementation?
In the above example I cannot use class parameter T as a parameter.
Upvotes: 8
Views: 4329
Reputation: 1656
Though some other answers are quite good, I would like to propose another workaround:
You could create an empty interface MyInterface
, and have all the classes in your list implement this interface. Then, you can change your class declaration to:
public class Publisher<T extends S, MyInterface>
which will achieve your purpose.
Upvotes: 6
Reputation: 7001
You are trying to access a generic type at runtime, which does not work in this case, because of type erasure.
The simplest way to fix this is to take a Class<T>
in the constructor, which will give you the type at run time, you can then check if the List contains the value you have been given.
public Publisher(Class<T> clazz) {
if(!SUPPORTED_CLASSES.contains(clazz)) {
System.out.println("Class not supported!");
}
}
Your code does not currently support subtypes, which may cause issues, unless you are ok with this (you may work on Lists, but not necessarily ArrayLists), this does beak the LSP though.
Upvotes: 13
Reputation: 170733
You'll need to pass the class into the constructor:
public Publisher(Class<T> clazz) {
if(!SUPPORTED_CLASSES.contains(clazz)) {
System.out.println("Class not supported!");
}
}
because T
isn't available at runtime: exactly the same code will be executed for new Publisher<T1>()
and new Publisher<T3>()
.
Upvotes: 4