Справочник по методам. Невозможно сделать статическую ссылку на нестатический метод
Может кто-нибудь объяснить мне,
зачем передавать нестатический метод-ссылку на метод 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){}
2 ответа
Ссылки на методы для нестатических методов требуют, чтобы экземпляр работал.
В случае с 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);
Как отметил Питер-Уолсер, так как 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
,
Короткий ответ:
Вы пытаетесь получить доступ к статическому методу через класс.
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);
}