Статическая ссылка (с::) на метод, возвращающий интерфейс

У меня есть несколько предустановленных статических "процессоров" , реализующих один и тот же метод, например:

default double process(double num){

Пример:

public class Test {
    public static void main(String[] args) {
        test(Test::processor1, 1d);
        test(Test::processor2, 1d);
    }

    static double processor1(double num){
        return num * 10;
    }

    static double processor2(double num){
        return num * 20;
    }
    //...

    static void test(Function<Double, Double> f, double d){
        // Do something util here
        System.out.println(f.apply(d));
    }   
    ...

Теперь представьте, что у меня есть некоторые объекты, которые могут предоставить список дополнительных "процессоров" .

Я пытаюсь использовать interface для определения этих дополнительных "процессоров" .

    static interface IProcessor{
        double process(double num);
    }

Реализация объекта с дополнительными "процессорами":

    static class SomeObject{
        // Just return one but should be a list...
        static IProcessor getExtraProccessors(){
            return new IProcessor(){
                public double process(double num){
                    return num * 30;
                }
            };
        }   
    }  

Здесь все компилируется и отлично работает. Но теперь я застрял.

Использование SomeObject::getExtraProccessors У меня есть ссылка на статический метод, возвращающий интерфейс, как я могу вызвать метод интерфейса?

Моя первая попытка была с

test(SomeObject::getExtraProccessors::process, 1d);

Но это не компилируется, давая The target type of this expression must be a functional interface

Итак, пожалуйста, не могли бы вы сказать мне, возможно ли это, и если да, то как? И если это невозможно, как мне это сделать?

Ответ 1

test(SomeObject.getExtraProccessors()::process, 1);
  • SomeObject.getExtraProccessors() возвращает экземпляр функционального интерфейса IProcessor.
  • SomeObject::getExtraProccessors - это ссылка на метод статического метода getExtraProccessor класса SomeObject.

Ответ 2

Как насчет использования выражения лямбда вместо ссылки на метод:

test(d-> SomeObject.getExtraProccessors().process(d), 1d);

Ответ 3

Я думаю, вам не нужно создавать анонимный внутренний класс, который реализует IProcessor. Фактически, если вы собираетесь работать с double, вам не нужен интерфейс IProcessor. Java предоставляет интерфейс DoubleUnaryOperator, который предназначен именно для этого.

Если вы хотите вернуть список "процессоров", вы можете сделать это следующим образом:

static class SomeObject {

    static List<DoubleUnaryOperator> getExtraProccessors() {
        return new ArrayList<>(Arrays.asList(Test::processor1, Test::processor2));
    }   
}  

Затем, если вы измените свой метод test на:

static void test(DoubleUnaryOperator f, double d) {
    // Do something util here
    System.out.println(f.applyAsDouble(d));
} 

Вы можете использовать его следующим образом:

test(SomeObject.getExtraProcessors().get(0), 1);