Ссылка На Метод. Не может сделать статическую ссылку на нестатический метод

может кто-нибудь объяснит мне,
зачем передавать нестатический метод-ссылка на метод 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;
   }
}

чтобы лучше понять, как это работает, можно рассмотреть эквивалентность кода методу reference 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.