Я хотел бы использовать новые ссылки на методы Java 8 для обеспечения большей проверки некоторого кода во время компиляции.
Скажем, у меня есть метод validateMethod
, который требует одного параметра: "метод", подлежащий проверке. Например:
validateMethod(foo, "methodA");
Здесь метод будет проверять, что foo#methodA()
существует во время выполнения.
Используя ссылки на методы, я бы хотел:
validateMethod(foo::methodA);
Таким образом, существование метода будет проверяться во время компиляции.
Проблема в том, что, по-видимому, ссылки на методы имеют для функционального интерфейса. Например, это:
Object dummy = foo::methodA;
Генерирует ошибку: "Целевой тип этого выражения должен быть функциональным интерфейсом".
Если я создаю функциональный интерфейс, который имеет совместимую подпись с методом methodA
, он работает:
@FunctionalInterface
public interface MyFunctionalInterface
{
public String run();
}
MyFunctionalInterface dummy = foo::methodA;
Теперь существование foo#methodA()
проверяется во время компиляции, чего я хочу!
Но...
Скажем, validateMethod
не знает подписи метода, который он должен проверить. Можно ли еще реализовать его?
Предположим, что мы не заботимся о двусмысленности и перегруженных методах. Возможно ли в Java 8 реализовать какой-то метод, который приведет к проверке любой ссылки на метод?
Например:
public class Foo
{
public String methodA()
{
return "methodA";
}
public String methodB(String str)
{
return "methodB";
}
public String methodC(String str, int nbr)
{
return "methodC";
}
}
Foo foo = new Foo();
validateMethod(foo::methodA); // Compile
validateMethod(foo::methodB); // Compile
validateMethod(foo::methodC); // Compile
validateMethod(foo::methodD); // Error!
Можно ли реализовать validateMethod
таким образом, чтобы любая ссылка на метод была принята, поэтому существование метода будет проверено во время компиляции?
Я пробовал:
public void validateMethod(Object obj){}
Но это не работает: "Целевой тип этого выражения должен быть функциональным интерфейсом"
Это будет работать:
@FunctionalInterface
public interface MyFunctionalInterface
{
public String run();
}
public void validateMethod(MyFunctionalInterface param){}
Но только для methodA
класса Foo
, поскольку его подпись (без параметра) совместима с сигнатурой метода функционального интерфейса!
Можно ли реализовать функциональный интерфейс MyFunctionalInterface
таким образом, чтобы любая ссылка метода была допустимым параметром и поэтому была бы проверена во время компиляции?
Какие-либо другие способы проверки существования метода во время компиляции?