Интерфейс JDK для обработки общего параметра

Есть ли интерфейс JDK, который выглядит примерно так:

public interface Callback<T> {
    public void process(T t);
}

Требование - реализовать обратный вызов, который запускает код, но ничего не возвращает.

Я мог бы написать свой собственный (просто используя здесь пример кода), но я бы хотел использовать существующее колесо, если оно существует, а не заново его.

Ответы

Ответ 1

В Java 8 класс java.util.function.Consumer делает именно то, что вы хотите.

Он имеет один нестандартный метод, который принимает общий тип и ничего не возвращает:

public interface Consumer<T> {

    void accept(T t);

    default Consumer<T> andThen(Consumer<? super T> after) {
        // ...
    }
}        

Ответ 2

Итак, вам нужно что-то вроде

interface Foo<T>
    bar(T)

Только 3 интерфейса в JDK похожи на

java.nio.file.DirectoryStream$Filter<T>

    boolean accept(T entry) throws IOException;


java.lang.Comparable<T>

    int compareTo(T o);


javax.xml.ws.Provider<T>

    T invoke(T request);

Очевидно, вам это не понравится.

Async IO имеет интерфейс обратного вызова, но он немного сложнее:

java.nio.channels.CompletionHandler<V,A>

    void completed(V result, A attachment);

    void failed(Throwable exc, A attachment);

Ответ 3

Нет, я не верю в такой интерфейс. В настоящее время существует такой интерфейс, называемый Block (с помощью метода apply, я думаю), в JDK 8... хотя имя может меняться между ними время от времени.

Ответ 4

Это выглядит как Guava Function, за исключением того, что функция разрешает возвращать что-то. Таким образом, это выглядит как

public interface Callback<T> extends Function<T, Void> {
}

Не является частью JDK, но Guava настолько часто используется, что вы можете найти его удобным.

Ответ 5

Реальный вопрос вот почему? Почему вы считаете, что определение вашего интерфейса для этого хуже, чем использование Java? Что вы собираетесь выиграть? Вы потеряете возможность выбрать подходящее имя. Я думаю об этом. Если у вас была причина использовать существующий интерфейс, предоставляемый библиотеками Java, вы уже знаете его имя, потому что вы знаете, с какой частью библиотеки вы планируете взаимодействовать. Создание интерфейса одним способом не изобретает колесо.

Ответ 6

По моему опыту, в JDK нет такого интерфейса. Generics появилась только в конце игры Java. До этого требовалось передать несколько типизированных аргументов для обратного вызова безопасным способом полу-типа и без предварительного знания структуры этих аргументов (я говорю "полутипный сейф", потому что прослушиватели событий были изобретены для тестирования типа события и при необходимости отбрасывать). Вы не могли бы построить этот механизм без дженериков, и они никогда не перепроектировали весь JDK, чтобы иметь общие представления (кроме API коллекций и нескольких других). Это было бы масштабное мероприятие с небольшим успехом (ведь все работает как ожидалось).

Следовательно, шаблон наблюдателя/слушателя, который распространен в библиотеках JDK (см. java.util.EventObject, java.util.EventListerner и их использование). Java также верит в то, что в процессе определения интерфейса будет немного более подробным, при реализации EventListener. Для более ясных реализаций, специализированные реализации этого шаблона должны сделать имя метода обратного вызова, чтобы продемонстрировать цель кода (который обычно также соответствует имени события). Например, ActionEvent#actionPerformed(ActionEvent e).

Еще одна причина, по которой этот интерфейс отсутствует, заключается в том, что он не используется в самом JDK. Иногда вы хотите Callback<T> других для Callback<T, V> или даже Callback<T, R, V> и т.д. Предоставление этих интерфейсов без каких-либо реальных целей использования (внутри JDK) действительно не очень политическая политика. Отсутствие поддержки таких полезных конструкций является основной причиной, по которой существуют Гуава и Apache Commons (среди прочих).

В любом случае, я согласен с @JB Nizet, что вы должны использовать Guava. Мы не указали, почему и как вы используете интерфейс, так что у вас много места для спекуляции, но по любой причине у Guava, вероятно, будут другие функции, которые могут пригодиться.

Ответ 7

Если вы хотите применить шаблон проектирования Observer, Java поддерживает его в своей стандартной библиотеке с JDK 1.0. Интерфейс, который вы ищете, - java.util.Observer. Другая сторона шаблона - класс java.util.Observable. В основном, вы расширяете java.util.Observable, а затем регистрируете наблюдателей (насколько я понимаю, Наблюдатель может наблюдать одновременно более одного наблюдаемого). Это довольно древний материал, так что будьте осторожны: никаких дженериков.