2013-03-26 3 views
3

У меня есть вопрос относительно правильной сигнатуры метода в интерфейсе и почему. Мое событие параметризуется типом, однако, если интерфейс также имеет <T>, который использует его в сигнатуре метода? Если да, почему, почему бы и нет?Использование дженериков в интерфейсе

public interface MyListener { 
    void beforeAction(final MyEvent event); 
} 

И

public class MyEvent<T> extends EventObject { 

    // code 
} 

ответ

4

Если MyEvent спараметрирован с типом, то MyListener нужно будет указать либо как

public interface MyListener<T> { 
    void beforeAction(final MyEvent<T> event); 
} 

или если существуют различные типы MyEvents, которые не являются конкретно к прилагаемому MyListener, то:

public interface MyListener { 
    <T> void beforeAction(final MyEvent<T> event); 
} 

Или, как сказал Томас, вы можете просто игнорировать тип Т в целом:

public interface MyListener { 
    void beforeAction(final MyEvent<?> event); 
} 

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

+1

Или если 'T' не имеет значения в этом случае, вы можете сделать' void beforeAction (final MyEvent event); ' – Thomas

+1

Не могли бы вы объяснить, почему тоже? – LuckyLuke

+0

Я не думаю, что есть какая-то причина, по которой он избавляется от предупреждений компилятора, и несколько позволяет вам принудительно вводить ограничения типа во время компиляции. Информация о типе сохраняется во время выполнения. Как вы увидите из [таких вопросов, как этот] (http://stackoverflow.com/q/15629552/586086), система дженериков Java полностью распалась. –

2

Если тип T не имеет значения в вашем слушателе, вы должны, по крайней мере, определить метод как void beforeAction(final MyEvent<?> event);, чтобы избавиться от предупреждения и сохранить общие возможности. Без какого-либо типа компилятор отключит все проверки типов для этого метода.

Если вы хотите иметь разных слушателей для различных типов событий, вы должны добавить T в свой интерфейс, как, как уже указывал Андрей.

Таким образом, вы можете создать несколько реализаций прослушивателя без необходимости ручной настройки (и, следовательно, ошибок), например. что-то вроде этого:

public class StringListener implements MyListener<String> { 
    void beforeAction(final MyEvent<String> event) { 
    ... 
    } 
} 

public class NumberListener implements MyListener<Number> { 
    void beforeAction(final MyEvent<Number> event) { 
    ... 
    } 
} 

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

Обратите внимание, что это не относится к анонимным классам или локальным переменным - в этих случаях происходит стирание типа.

+0

Вы бы рекомендовали мне иметь 'T' в слушателе или использовать'? ' – LuckyLuke

+0

@LuckyLuke, что на самом деле зависит от того, что вы хотите сделать с этим интерфейсом. В большинстве случаев я хотел бы добавить 'T' в интерфейс и определить его в реализации, как показано выше. – Thomas

Смежные вопросы