Java get the second generic types

374 views Asked by At

I'm struggling to get the type of second generic from an object.

The abstract class takes two Generic types T and S

abstract class Concept<T, S> {
    
    public Concept() { 
     //do nothing
    }

    public final Class<?> getTypeParam() {
    
        ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericSuperclass();

        Class<?> result = (Class<?>) parameterizedType.getActualTypeArguments()[0];

        return result;
    }               
}

In this derivative class one (in this case T) generic is defined:

public class Decision<S> extends Concept<String, S>{
    
    public Decision () {
        super();
        System.out.println(getTypeParam()); //returns the first parameterized type. How do I get the second one?
    }       
}

When I now run it I get the first parmerized generic back. Great. But how do I get out the second one?

public class Main {

    public static void main(String[] args){

        Decision<Boolean> myBooleanDecision = new Decision<>();
    }
}
2

There are 2 answers

0
GhostCat On

Your problem is based on the fact that you aren't clear on your requirements.

Your method signature looks like this: public final Class<?> getTypeParam()

But what you overlook: the number of type parameters with your classes isn't fixed. The base Concept class allows for two type parameters, but the Decision subclass "fixes" the first parameter to String.

Thus: you have to decide what you actually want/need. There are various solutions, like:

  • public final Class<?> getFirstParam() ... to return index 0, always
  • public final Class<?> getSecondParam() ... to return index 1, always (which obviously fails for classes that only have 1 generic type parameter)
  • public final List<Class<?>> getParams() ... to return a list with all entries

That is your option space. Which solution to pick solely depends on the purpose of that method (which we don't know anything about).

Personally, I would go for the third option, as that will work for 0, 1, ... n type parameters, without any changes.

0
Edwin On

Change the decleration:

Decision<Boolean> myBooleanDecision = new Decision<>("Binary Decision") {};

Now this will result in the second generic:

Class<?> result = (Class<?>) parameterizedType.getActualTypeArguments()[0];

Output is:

class java.lang.Boolean