ParameterizedType.getRawType () возвращает jlrType, а не Class? - PullRequest
22 голосов
/ 24 апреля 2011
ParameterizedType parameterized =
    (ParameterizedType) List.class.getMethod("iterator").getGenericReturnType();
Type raw = parameterized.getRawType();

ParameterizedType#getRawType() возвращает Type, а не Class<?> (хотя я понимаю, что java.lang.Class теперь реализует Type).Есть ли веская причина, почему getRawType() не объявляет тип возвращаемого значения Class<?>?Существуют ли крайние случаи, когда результат getRawType() может быть не Class<?>?

Этого достаточно, чтобы работать с j.l.r.Type как есть;это похоже на случай, когда они могли бы спасти нас от ударов.

Ответы [ 4 ]

13 голосов
/ 24 апреля 2011

Он должен возвращать Class объект, другого пути нет.

Почему?Кто знает, может быть, какой-то идеалистический уклон.Если бы он возвратил Class, это было бы единственным появлением Class в новых Type интерфейсах.

Настоящая проблема - это смешивание Class и Type.Ранее все типы были представлены в Class.Это было уже грязно, но все еще терпимо.Типов было не так много.

С новыми универсальными типами они должны были разработать более чистую и точную иерархию Type, независимую от Class.Вместо этого они включили Class с Type и создали больше беспорядка.Вся иерархия просто не имеет смысла.Любой новичок в теме и не знающий истории будет потрясен этой ерундой.

Я бы не отнес дизайн Type к высокому стандарту.Например, ParameterizedType определяет equals(), но не hashCode().Невозможно, чтобы две реализации ParameterizedType работали в одной хэш-карте.А подстановочный знак это тоже тип?Ада нет.

А название метода getRawType() просто идиотское.Это не имеет ничего общего с raw type.Он должен быть просто назван getClassOrInterface().Это было бы слишком многословно?Посмотрите на getActualTypeArguments() тогда.(И да, он возвращает фактические аргументы! Не поддельные!)

3 голосов
/ 24 апреля 2011

Реализация Sun ParameterizedType определила метод getRawType() для возврата Class<?>.Таким образом, он явно возвращает только Class<?>

Однако на моем пути к классам есть еще несколько реализаций ParameterizedType - из hibernate-validator, из aspectj, hibernate-annotations, jaxb.Некоторые из них возвращают Class<?>, некоторые - Type.Я не знаю, как они используются.

2 голосов
/ 16 октября 2013

Я думал об этом, и у меня есть предчувствие. Возможно, они хотели оставить возможность для будущего безумия, как это:

public class Z<L extends List<?>> {
    L<Double> test;
}

Это недопустимый код Java, но я думаю, что это ясно; new Z<ArrayList<?>>().test будет иметь тип ArrayList<Double>.

Если бы это было законно, ((ParameterizedType) test.getGenericType()).getRawType() вернул бы TypeVariable.

1 голос
/ 19 февраля 2015

Существуют и другие применения иерархии интерфейса Type, кроме api отражения.Например, библиотека генерации кода может определять пользовательские реализации.Сам JDK 8 имеет 3 различных реализации WildcardType.Если ParameterizedType.getRawType () вернул экземпляр класса, тогда вам нужно будет создать экземпляр класса в любое время.

Класс - это глубоко укоренившийся тип JVM, имеющий привязки к памяти, управляемой собственными силами.Чтобы создать экземпляр класса, вы должны иметь байтовый код, который определяет класс.Но в случае библиотеки генерации кода, байт-код еще даже не существует.Если бы им потребовалось, чтобы ParameterizedType возвратил класс, это ограничило бы применимость иерархии интерфейса Type только отражением api.

Это может показаться не таким уж большим делом, но и не является приведением.

ParameterizedType.getOwnerType () возвращает тип, поскольку он сам может быть либо классом, либо другим параметром ParameterizedType.Теоретически он может возвращать TypeVariable, так как следующее является допустимым Java:

<M extends Map<?,?>> M.Entry<?,?> first(M map) { ... }

Однако он скомпилирован как статическая ссылка на стирание переменной типа, в этом случае M.Entry будет скомпилирован как Map.Вступление.Вместо TypeVariable вызов getOwnerType () из API-интерфейса отражения будет Class, по крайней мере, согласно моим тестам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...