Доступ к параметру универсального типа во время выполнения? - PullRequest
1 голос
/ 08 июня 2010

Интерфейс диспетчера событий

public interface EventDispatcher {
    <T> EventListener<T> addEventListener(EventListener<T> l);
    <T> void removeEventListener(EventListener<T> l);
}

Осуществление

public class DefaultEventDispatcher implements EventDispatcher {

@SuppressWarnings("unchecked")
private Map<Class, Set<EventListener>> listeners = new HashMap<Class, Set<EventListener>>();

public void addSupportedEvent(Class eventType) {
    listeners.put(eventType, new HashSet<EventListener>());
}

@Override
public <T> EventListener<T> addEventListener(EventListener<T> l) {
    Set<EventListener> lsts = listeners.get(T); // ****** error: cannot resolve T
    if (lsts == null) throw new RuntimeException("Unsupported event type");
    if (!lsts.add(l)) throw new RuntimeException("Listener already added");
    return l;
}

@Override
public <T> void removeEventListener(EventListener<T> l) {
    Set<EventListener> lsts = listeners.get(T); // ************* same error
    if (lsts == null) throw new RuntimeException("Unsupported event type");
    if (!lsts.remove(l)) throw new RuntimeException("Listener is not here");
}

}

Использование

    EventListener<ShapeAddEvent> l = addEventListener(new EventListener<ShapeAddEvent>() {
        @Override
        public void onEvent(ShapeAddEvent event) {
            // TODO Auto-generated method stub

        }
    });
    removeEventListener(l);

Я отметил две ошибки с комментарием выше (в реализации). Есть ли способ получить доступ к этой информации во время выполнения?

Ответы [ 2 ]

2 голосов
/ 08 июня 2010

Нет, вы не можете ссылаться на 'T' во время выполнения.

http://java.sun.com/docs/books/tutorial/java/generics/erasure.html

update
Но что-то вроде этого позволит достичь аналогичного эффекта

abstract class EventListener<T> {
    private Class<T> type;
    EventListener(Class<T> type) {
        this.type = type;
    }
    Class<T> getType() {
        return type;
    }

    abstract void onEvent(T t);
}

И создать слушателя

EventListener<String> e = new EventListener<String>(String.class) {
    public void onEvent(String event) {
    }
};
e.getType();
0 голосов
/ 08 июня 2010

Вы не можете сделать это в подходе, который вы пытаетесь, из-за стирание . Однако, с небольшими изменениями в дизайне, я считаю, что вы можете достичь того, что вам нужно. Попробуйте добавить следующий метод в интерфейс EventListener:

public Class<T> getEventClass();

Каждая реализация EventListener должна указывать класс событий, с которыми она работает (я предполагаю, что T обозначает тип события). Теперь вы можете вызвать этот метод в своем методе addEventListener и определить тип во время выполнения.

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