Справочник по методу. Невозможно сделать статическую ссылку на нестатический метод
Может кто-нибудь объяснить мне,
почему передача нестатического метода-ссылки на метод File::isHidden
в порядке,
но передача метода ссылки на нестатический метод MyCass::mymethod
- дает мне
"Невозможно сделать статическую ссылку на нестатический метод" ?
public static void main(String[] args) {
File[] files = new File("C:").listFiles(File::isHidden); // OK
test(MyCass::mymethod); // Cannot make a static reference to the non-static method
}
static interface FunctionalInterface{
boolean function(String file);
}
class MyCass{
boolean mymethod(String input){
return true;
}
}
// HELPER
public static void test(FunctionalInterface functionalInterface){}
Ответы
Ответ 1
Ссылки методов на нестатические методы требуют, чтобы экземпляр работал.
В случае метода listFiles
аргумент равен FileFilter
с accept(File file)
. Когда вы работаете с экземпляром (аргументом), вы можете ссылаться на его методы экземпляра:
listFiles(File::isHidden)
который является сокращением для
listFiles(f -> f.isHidden())
Теперь почему вы не можете использовать test(MyCass::mymethod)
? Потому что у вас просто нет экземпляра MyCass
для работы.
Однако вы можете создать экземпляр, а затем передать ссылку метода на свой метод экземпляра:
MyCass myCass = new MyCass(); // the instance
test(myCass::mymethod); // pass a non-static method reference
или
test(new MyCass()::mymethod);
Ответ 2
Как отметил peter-walser, поскольку MyCass::mymethod
является методом экземпляра, он требует, чтобы экземпляр был преобразован в экземпляр Function
.
static
перед объявлением интерфейса просто делает его статическим интерфейсом, он не превращает каждый метод в статический.
Возможным решением было бы объявить метод внутри класса статическим:
class MyCass{
static boolean mymethod(String input){
return true;
}
}
Чтобы лучше понять, как это работает, вы можете рассмотреть код, эквивалентный ссылочной ссылке метода MyCass::mymethod
, которая (при условии вышеописанного измененного объявления MyClass
):
new FunctionalInterface{
boolean function(String file){
return MyClass.mymethod(file);
}
}
Ваш исходный код попытается выполнить сортировку перевода:
new FunctionalInterface{
boolean function(String file){
return _missing_object_.mymethod(); # mymethod is not static
}
}
Другая возможность заключается в использовании BiFunction
вместо FunctionalInterface
. В этом случае первым аргументом apply
будет объект, а второй будет аргументом mymethod
.
Ответ 3
Короткий ответ:
Вы пытаетесь получить доступ к статическому методу через класс.
test(MyCass::mymethod); // Cannot make a static reference to the non-static method
Такой же как
test(v -> MyCass.mymethod(v)); // static access
Решение
Сделайте функцию статичной
class MyCass {
static boolean mymethod(String input) {
return true;
}
}
Или используйте объект в качестве ссылки
public static void main(String[] args) {
MyCass myCass = new MyCass();
test(myCass::mymethod);
}