Разница между getGenericParameterTypes и getParameterTypes - PullRequest
7 голосов
/ 19 июля 2011

Я пытаюсь узнать разницу между getGenericParameterTypes и getParameterTypes методами. Я знаю, что один возвращает Class[], а другой Type[]. Но в чем реальная разница?

Рассмотрение методов:

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

Что я получу при вызове каждого из методов get для каждого из примеров методов?

Ответы [ 2 ]

7 голосов
/ 19 июля 2011

Я не могу точно сказать вам, что вы получите, но одно отличие состоит в том, что для метода 2 вы можете сказать, что тип параметра равен Class<String>, тогда как для метода 1 вы просто знаете, что есть параметр с именем T, но вы не знаете точный тип, за исключением того, что класс, где объявлено T, был бы подклассом конкретного класса для T.

Пример:

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

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

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

Для foo вы не сможете получить тип T во время выполнения (вы не будете знать, что это Baz), ни во время компиляции. Для bar вы сможете получить тип для T, поскольку он уже известен во время компиляции.

Еще одно отличие при взгляде на код:

Вызов getGenericParameterTypes() для метода 1 должен вернуть тип T, вызов его для метода 2 должен вернуть Class<String>. Однако, если вы вызовете getTypeParameters(), вы получите тип T для метода 1, но массив нулевой длины для метода 2.

Редактировать: поскольку вместо getTypeParameters() имелось в виду getParameterTypes(), вот разница, которую я вижу по коду:

Для метода 2 не будет никакой разницы, поскольку, если в сигнатуре не используются универсальные значения, getGenericParameterTypes() фактически вызывает getParameterTypes(). Для метода 1 getGenericParameterTypes() будет возвращено ParameterizedType, в котором указано, что параметр имеет имя T, тогда как getParameterTypes() вернет требуемый базовый класс типа, например, Class<Object> для <T> или Class<Number> для <T extends Number>.

5 голосов
/ 19 июля 2011

getGenericParameterTypes может возвращать другие виды Type с. getParameterType является отражением "pre-generics". Это означает, что T будет считаться java.lang.Object. Проверьте этот пример:

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

}

Вывод:

with GPT: T
with PT: class java.lang.Object
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...