Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between getGenericParameterTypes and getParameterTypes

I am trying to learn the difference between getGenericParameterTypes and getParameterTypes methods. I know that one returns Class[] and the other Type[]. But what is ther real difference?

Considering methods:

public void method1(T arg1)
public void method2(String arg2)

What would I get when invoking each of the get methods over each of the example methods?

like image 553
Tiago Veloso Avatar asked Jul 19 '11 12:07

Tiago Veloso


2 Answers

I can't exactly tell you what you would get, but one difference is that for method 2 you can tell the parameter type is Class<String> whereas for method 1 you'd just know there's a parameter named T, but you don't know the exact type except the class where T is declared would have been subclassed with a concrete class for T.

Example:

class Foo<T> {
   public void method1( T arg1 ) { ... }
}

class Bar extends Foo<Baz> { ... }

Foo<?> foo = new Foo<Baz>();
Bar bar = new Bar();

For foo you'd not be able to get the type of T at runtime (you'd not know it's Baz) nor at compile time. For bar you'd be able to get the type for T since it is already known at compile time.

Another difference when looking at the code:

Calling getGenericParameterTypes() on method 1 should return the T type, calling it for method 2 should return Class<String>. However, if you call getTypeParameters() you'd get the T type for method 1 but a zero-length array for method 2.

Edit: since getParameterTypes() was meant instead of getTypeParameters() here's the difference I can see from the code:

For method 2 there would be no difference, since if no Generics are used in the signature, getGenericParameterTypes() actually calls getParameterTypes(). For method 1 getGenericParameterTypes() would return a ParameterizedType that states the parameter has name T whereas getParameterTypes() would return the required base class of the type, e.g. Class<Object> for <T> or Class<Number> for <T extends Number>.

like image 171
Thomas Avatar answered Nov 05 '22 12:11

Thomas


getGenericParameterTypes can return other kind of Types. getParameterType is the "pre-generics" reflection. This means T will be considered as java.lang.Object. Check this example:

public class Generics<T> {

    public void method1(T t) {
    }

    public static void main(String[] args) throws Exception {
        Method m = Generics.class.getMethod("method1", Object.class);
        for (Type t : m.getGenericParameterTypes()) {
            System.out.println("with GPT: " + t);
        }
        for (Type t : m.getParameterTypes()) {
            System.out.println("with PT: " + t);
        }
    }

}

The output is:

with GPT: T
with PT: class java.lang.Object
like image 36
Eduardo Costa Avatar answered Nov 05 '22 13:11

Eduardo Costa