Интерфейс 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, а затем регистрируете наблюдателей (насколько я понимаю, Наблюдатель может наблюдать одновременно более одного наблюдаемого). Это довольно древний материал, так что будьте осторожны: никаких дженериков.
Ответ 8
Я использовал Callable (http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Callable.html) для реализации обратных вызовов/функторов в java.
interface Callable<V> {
public V call();
}
Вы можете обработать это, используя материал Executors в java.util.concurrent.
Ответ 9
Он называется обработкой аннотации. JSR 269: API-интерфейс для подключаемых аннотаций определяет API и является частью JDK 6. Вы можете начать с здесь и здесь.