Какой будет подпись во время выполнения?

1

У меня есть проблема с пониманием стирания стилей Java, когда речь идет о ограниченных типах. Учти это:

class Event {} // From the API
class FooEvent extends Event {}

abstract class Foo<EventType extends Event> {
    public abstract <E extends EventType> void onEventCaught(E event);
}

class Bar extends Foo<FooEvent> {
    @Override
    public void onEventCaught(FooEvent event) {

    }
}

По-видимому, это компилируется без проблем. Вопрос, который я задаю себе, - это то, для каких типов параметров объявлен Bar#onEventCaught(), здесь (как в том, что думает отражение)?

Это onEventCaught(FooEvent event) или возможно onEventCaught(Event event)?

  • 0
    Не называйте ваши родовые типы как классы, которые у вас уже есть. Например, вы можете создать класс, подобный class Foo<String> но для этого класса String будет представлять универсальный тип, а не тип java.lang.String , поэтому вы не сможете использовать внутри него String s = "hello world" . Называть универсальные типы проще, например, class Foo<T> .
  • 0
    @Pshemo Отмечено, я думаю, что это поможет избежать путаницы на моей стороне в будущем ...
Теги:
reflection
type-erasure

1 ответ

3
Лучший ответ

Из спецификации языка Java

Стирание переменной типа (§4.4) является стиранием его левого края.

У тебя есть

<EventType extends Event> 

а также

<E extends EventType>

Крайней левой границей E является EventType, которая является другой переменной типа, самой левой границей которой является Event. Таким образом, стирание E в

public abstract <E extends EventType> void onEventCaught(E event);

это Event.

Переменные типа отображаются в файлах .class, и вы можете использовать их в отражении.

Class<?> clazz = Foo.class;
TypeVariable typeVariable = clazz.getTypeParameters()[0];
Type type = typeVariable.getBounds()[0];

System.out.println(typeVariable);
System.out.println(type);

печать

EventType
class com.example.Event
  • 0
    Поэтому, когда метод аннотируется с помощью, скажем, @interface Subscribe и кто-то просматривает класс с помощью отражения для методов с Subscribe он увидит метод onEventCaught(Event event) , это правильно?
  • 1
    @WorldSEnder Это зависит от того, что они используют. Если они используют Method#getParameterTypes они увидят Event . Если они используют Method#getParameters который возвращает Parameter[] , они увидят E Хотя вы всегда можете найти, что такое E с помощью некоторого обратного инжиниринга для переменных типа или класса метода.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню