2011-07-19 17 views
7

Próbuję poznać różnicę między metodami getGenericParameterTypes i getParameterTypes. Wiem, że jeden zwraca Class[], a drugi. Ale jaka jest prawdziwa różnica?Różnica między getGenericParameterTypes i getParameterTypes

metody rozważenie:

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

Co byłoby uzyskać przy wywołaniu każdej z metod get nad każdym z przykładowych metod?

Odpowiedz

6

Nie mogę dokładnie powiedzieć, co dostałeś, ale jedną różnicą jest to, że dla metody 2 możesz powiedzieć, że typ parametru to Class<String>, podczas gdy dla metody 1 po prostu wiesz, że jest parametr o nazwie T, ale ty nie nie zna dokładnego typu, z wyjątkiem klasy, dla której zadeklarowano T, zostałby poddany podklasie z konkretną klasą dla T.

Przykład:

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

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

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

Dla foo nie byłoby w stanie uzyskać typ T przy starcie (nie, że wiem, że to Baz) ani w czasie kompilacji. W przypadku bar można uzyskać typ dla T, ponieważ jest on już znany podczas kompilacji.

Kolejna różnica, gdy patrząc na kod:

Wywołanie getGenericParameterTypes() na metody 1 powinien wrócić typ T, nazywając ją do metody 2 należy powrócić Class<String>. Jednakże, jeśli zadzwonisz getTypeParameters() chcesz uzyskać T typ dla metody 1, ale tablicę o zerowej długości w przypadku metody 2.

Edycja: od getParameterTypes() miał zamiast getTypeParameters() tutaj jest różnica widzę z kodem:

Dla metody 2 nie byłoby różnicy, ponieważ jeśli w podpisie nie są używane żadne generyczne, getGenericParameterTypes() faktycznie wywołuje getParameterTypes(). W przypadku metody 1 getGenericParameterTypes() zwracana jest wartość ParameterizedType, która określa, że ​​parametr ma nazwę T, podczas gdy getParameterTypes() zwraca wymaganą klasę podstawową typu, np. Class<Object> dla <T> lub Class<Number> dla <T extends Number>.

+0

przykro mi, ja popełniłem błąd. Miałem na myśli 'getParameterTypes', a nie' getTypeParameters'. Jest różnica. Ledwo zauważyłem. Czy możesz edytować swoją odpowiedź, aby odreagować tę zmianę? –

+0

@ Santiago dodał informacje – Thomas

+0

Dziękuję, bardzo docenione. –

5

getGenericParameterTypes może zwrócić inny rodzaj Type s. getParameterType to odbicie "pre-generics". Oznacza to, że T zostanie uznane za java.lang.Object. Sprawdź ten przykład:

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); 
     } 
    } 

} 

Wyjście jest:

with GPT: T 
with PT: class java.lang.Object