Имейте в виду, что вам лучше всего создать интерфейс для вашего конкретного использования. Если вы выбрали callable , то вам следует заменить T выше на любой тип возвращаемого значения, который вы ожидаете, например, String .
В ответ на свой комментарий ниже вы могли бы сказать:
publicintmethodToPass() { // do something }
publicvoiddansMethod(int i, Callable<Integer> myFunc) { // do something }
затем вызовите ее, возможно, используя анонимный внутренний класс:
В дополнение к отличному ответу jk., теперь вы можете передать метод более легко, используя лямбда-выражения (в Java 8). Сначала немного предыстории. Функциональный интерфейс - это интерфейс, который имеет один и только один абстрактный метод, хотя он может содержать любое количество методов по умолчанию (новых в Java 8) и статических методов. Лямбда-выражение может быстро реализовать абстрактный метод без всего ненужного синтаксиса, необходимого, если вы не используете лямбда-выражение.
Список формальных параметров, разделенных запятыми, заключен в круглые скобки. Метод CheckPerson.test содержит один параметр, p, который представляет экземпляр класса Person.
Примечание: Вы можете не указывать тип данных параметров в лямбда-выражении. Кроме того, вы можете не заключать в круглые скобки, если есть только один параметр. Например, следующее лямбда-выражение также допустимо:
Если вы укажете единственное выражение, среда выполнения Java вычислит выражение и затем вернет его значение. В качестве альтернативы, вы можете использовать оператор return:
Оператор return не является выражением; в лямбда-выражении вы должны заключать операторы в фигурные скобки ({}). Однако вам не обязательно заключать вызов метода void в фигурные скобки. Например, следующее является допустимым лямбда-выражением:
email -> System.out.println(email)
Обратите внимание, что лямбда-выражение очень похоже на объявление метода; вы можете рассматривать лямбда-выражения как анонимные методы —methods без имени.
Вот как вы можете "передать метод", используя лямбда-выражение:
classA { publicstaticvoidmethodToPass(int i) { // do stuff } }
import java.util.function.IntConsumer;
classB { publicvoiddansMethod(int i, IntConsumer aMethod) { /* you can now call the passed method by saying aMethod.accept(i), and it will be the equivalent of saying A.methodToPass(i) */ } }
Приведенный выше пример можно еще больше сократить, используя :: оператор.
publicC() { b.dansMethod(100, A::methodToPass); }
Ответ 4
Благодаря Java 8 вам не нужно выполнять приведенные ниже шаги, чтобы передать функцию методу, для этого и существуют лямбда-выражения, см. Руководство Oracle по лямбда-выражениям. Остальная часть этого поста описывает, что нам приходилось делать в старые недобрые времена, чтобы реализовать эту функциональность.
Обычно вы объявляете свой метод как принимающий некоторый интерфейс с одним методом, затем вы передаете объект, который реализует этот интерфейс. Пример находится в commons-collections , где у вас есть интерфейсы для замыкания, преобразования и предиката, а также методы, в которые вы передаете их реализации. Guava - это новые улучшенные коллекции commons, вы можете найти там эквивалентные интерфейсы.
Так, например, в commons-collections есть org.apache.commons.collections.CollectionUtils, в котором есть множество статических методов, которые принимают передаваемые объекты, чтобы выбрать один наугад, есть один с именем exists с такой сигнатурой:
Он принимает объект, который реализует предикат интерфейса, что означает, что в нем должен быть метод, который принимает некоторый объект и возвращает логическое значение.