Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - Use Class parameter in method parameter

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.

like image 803
FazoM Avatar asked Oct 19 '17 12:10

FazoM


2 Answers

Why this doesn't work

You are trying to access a generic type at runtime, which does not work in this case, because of type erasure.

How to fix

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.

Example code

public Publisher(Class<T> clazz) {
    if(!SUPPORTED_CLASSES.contains(clazz)) {
        System.out.println("Class not supported!");
    }
}

Possible issues

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.

like image 53
jrtapsell Avatar answered Sep 30 '22 01:09

jrtapsell


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.

like image 39
Turtle Avatar answered Sep 29 '22 23:09

Turtle