Как стать автором
Обновить

Практическое использование multiple bounds generic в Java

Время на прочтение 2 мин
Количество просмотров 7.8K

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


Наткнулся на проблему: надо послать уже существующее событие (GWT) по нажатию кнопки, но перед посылкой поставить атрибут (Command). Казалась бы, при чём здесь шаблоны…
А вот при чём:


Сам метод для создания кнопки тривиален, command это поле класса:


Component createEventLink(String link, final Event<?> event) {
    TextButton button = new TextButton(link, new SelectHandler() {
        @Override
        public void onSelect(SelectEvent e) {
            //event.setCommand(command);
            bus.fire(event);
        }
    });
    return new WidgetComponent(button);
}

Проблема в строчке:


//event.setCommand(command);

Такого метода у объекта Event нет. Решение, вроде, очевидное: унаследовать наше события от промежуточного класса CommandEvent, у которого будет этот метод и который унаследован от Event. Наш метод выглядит теперь так:


Component createEventLink(String link, final CommandEvent<?> event) {
    TextButton button = new TextButton(link, new SelectHandler() {
        @Override
        public void onSelect(SelectEvent e) {
            event.setCommand(command);
            bus.fire(event);
        }
    });
    return new WidgetComponent(button);
} 

Эврика? Ха! Тут мы обнаруживаем, что одно из наших событий уже унаследовано от другого дочернего класса (e.g. GwtEvent) и никак не может наследовать наш класс CommandEvent.
Следующий шаг — создаём интерфейс ICommandEvent c методом setCommand() и каждое наше событие реализует его. Наш метод выглядит теперь так:


Component createEventLink(String link, final Event event) {
    TextButton button = new TextButton(link, new SelectHandler() {
        @Override
        public void onSelect(SelectEvent e) {
            if (event instanceof ICommandEvent) {
                ((ICommandEvent) event).setCommand(command);
            } else {
                throw new IllegalStateException("Only ICommandEvent allowed");
            }
            bus.fire(event);
        }
    });
    return new WidgetComponent(button);
}

Ну некрасиво! К тому же в него можно передать любое событие, а обнаружится это только при запуске, что нехорошо.


И тут пора вспомнить о теме этой заметки — multiple bounds generic в Java. С ними наш метод выглядит так:


<E extends Event<?> & ICommandEvent> Component createEventLink(String link, final E event) {
    TextButton button = new TextButton(link, new SelectHandler() {
        @Override
        public void onSelect(SelectEvent e) {
            event.setCommand(command);
            bus.fire(event);
        }
    });
    return new WidgetComponent(button);
}

Ровно то, что и требовалось.

Теги:
Хабы:
+13
Комментарии 6
Комментарии Комментарии 6

Публикации

Истории

Работа

Java разработчик
359 вакансий

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн