Ссылка на метод Java (передать метод в качестве параметра) - PullRequest
0 голосов
/ 10 октября 2018

Я хочу передать метод в качестве параметра в методе, подобном

callMethod (someArg, methodToPass )

И в определении callMethod я хочу вызватьэто фн т.е.MethodToPass, т.е. в другом java-файле, и аргументы для fn MethodToPass инициализируются только в этом callMethod.

Скажите, пожалуйста, как мне это сделать ??

Ответы [ 2 ]

0 голосов
/ 10 октября 2018

Вы можете объявить @FunctionalInterface, содержащий метод (хотя есть вероятность, что JDK уже предоставил его).

@FunctionalInterface
interface MethodToPass {
    void methodToCall(int someArg);
}

Затем вы можете передать метод в качестве ссылки:

class YourClass {
    // note same signature as the inferface method
    public void methodToPass(iont arg) { 
        System.out.println("called with " + arg);
    }
}

class OtherClass {
    public static void main(String[] args) {
        YourClass c = new YourClass();
        callMethod(c::methodToPass);
    }
    public void callMethod(MethodToPass method) {
        for (int i = 1; i < 4; i++) {
            method.methodToCall(i);
        }
    }
}

Опять же, наиболее распространенные подписи уже существуют в JDK - в данном случае это Consumer<Integer>.

0 голосов
/ 10 октября 2018

Это зависит от подписи вашего "methodToPass".

Например, если ваш метод принимает один аргумент и имеет тип возвращаемого значения, вы можете использовать Function<X,Y>:

public static <X,Y> Y callMethod (X arg, Function<X,Y> func) {
    return func.apply(arg);
}

и вызовите его с помощью:

Integer result = callMethod ("abc", String::length);

Если у вашего метода есть подпись, которая не соответствует предопределенным функциональным интерфейсам, вы можете создать пользовательский интерфейс.

Любой универсальный:

public interface MyFunc<T1,T2,T3,T4,T5>
{
    public void apply (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5);
}

или нет:

public interface MyFunc
{
    public void apply (Type1 t1, Type2 t2, Type3 t3, Type4 t4, Type5 t5);
}

, где TypeN представляют фактические классы.

Теперь callMethod становится (в неуниверсальной версии):

public static void callMethod (MyFunc method) {
    Type1 a1 = ...
    Type2 a2 = ...
    Type3 a3 = ...
    Type4 a4 = ...
    Type5 a5 = ...
    method.apply(a1,a2,a3,a4,a5);
}

И вы называете это с помощью:

callMethod (SomeClass::methodToPass);

Где methodToPass определяется как:

static void methodToPass (Type1 t1, Type2 t2, Type3 t3, Type4 t4, Type5 t5) {
    ...
}
...