Получить тип возвращаемого значения для унаследованного универсального метода - PullRequest
1 голос
/ 21 октября 2019

У меня есть эти 3 класса

public class Box<O> {

    public O getItem() {...}

}
public class CoolBox extends Box<Integer> { ... }
public class AmazingBox extends CoolBox { ... }

В какой-то момент в моем коде мне нужно получить тип возврата метода getItem() для класса AmazingBox,но когда я получаю доступ к его методам через отражение, я получаю Object в качестве возвращаемого типа вместо Integer.

Есть ли способ (обычные java или дополнительные библиотеки) получить Integer в качестве возвращаемого типа?

Это код, который я использовал для получения типа возвращаемого значения:

Class<?> c = AmazingBox.class;  // This is not how i get the class but its for demonstration purposes

Method m = c.getMethod("getItem");

Type t = m.getReturnType();

Ответы [ 2 ]

1 голос
/ 21 октября 2019

При наследовании вы можете использовать дженерики для наследования классов и соответственно создавать нижние или верхние границы. Если вы этого не сделаете, предположите, что вы работаете без использования обобщенных элементов и не получите безопасность типов при наследовании неуниверсальных классов.

Короче говоря, если вы перейдете на гибрид, type erasures вступит в силу со следующимиправила (документация к соглашению)

Тип Erasure

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

  • Заменить все параметры типов в обобщенных типах с их границами или Object, если параметры типа не ограничены. Поэтому созданный байт-код содержит только обычные классы, интерфейсы и методы.
  • Вставьте приведение типов в случае необходимости, чтобы сохранить безопасность типов.
  • Создайте методы-мосты для сохранения полиморфизма в расширенных обобщенных типах.

Стирание типов гарантирует, что новые классы для параметризованных типов не создаются;следовательно, генерики не несут затрат времени выполнения.

1 голос
/ 21 октября 2019

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

Используя этот фрагмент кода, он возвращает правильный тип

Class<?> clazz = AmazingBox.class;
GenericsContext genericsContext = GenericsResolver.resolve(clazz);
Method method = clazz.getMethod("getItem");
Type methodReturnType = genericsContext.method(method).resolveReturnType();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...