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

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

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

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


Наткнулся на проблему: надо послать уже существующее событие (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);
}

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

Теги:
Хабы:
Всего голосов 19: ↑16 и ↓3+13
Комментарии6

Публикации

Истории

Работа

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

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

27 августа – 7 октября
Премия digital-кейсов «Проксима»
МоскваОнлайн
3 – 18 октября
Kokoc Hackathon 2024
Онлайн
10 – 11 октября
HR IT & Team Lead конференция «Битва за IT-таланты»
МоскваОнлайн
25 октября
Конференция по росту продуктов EGC’24
МоскваОнлайн
7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн