Статическая ссылка (с::) на метод, возвращающий интерфейс
У меня есть несколько предустановленных статических "процессоров" , реализующих один и тот же метод, например:
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);