Вы не можете создать лямбда-выражение с определенным c захваченным значением, например 123
, в варианте ссылки на чистый метод. . Вам нужно написать явную лямбда-версию со стрелкой, если вы хотите передать захваченные значения, отличные от экземпляра для выполнения метода. Подробнее о захвате значений в лямбдах читайте в этом ответе: Enhanced 'для' l oop и лямбда-выражений
Единственное исключение - объект, который сам становится первым параметром. Предположим, что подпись ожидает Получателя строки:
public void something(Consumer<String> job) {
...
Вышеупомянутая подпись позволит вам написать следующие вызовы:
String myString = " Hey Jack ";
something(myString::trim);
something(s -> s.trim());
Оба делают то же самое, и это, возможно, неинтуитивно, потому что один принимает аргумент (ссылка на экземпляр myString
), а другой, похоже, не принимает его (но на самом деле он тоже). Это работает, потому что компилятор пробует два возможных разрешения для ссылки на лямбда-метод (версия выше с ::
). С одной стороны, компилятор может применять сигнатуры, как если бы вызываемый метод не имел никаких параметров и не нуждался в передаче. Это случай myString.trim
. Но компилятор также проверит, существует ли stati c метод String.trim(myString)
(которого, к счастью, нет). Если вы хотите вызвать метод stati c без каких-либо параметров, вам нужно будет вызвать идентификатор класса со ссылкой на функцию следующим образом:
something(String::trim); // this version of trim does not exist.
Иногда это даже проблема, потому что если класс предлагает stati c версию метода и версию, связанную с экземпляром, вы получаете двусмысленность:
public void somethingElse(Function<Integer, String> transformation) {...}
// This will not compile:
somethingElse(Integer::toString);
Приведенный выше пример не будет компилироваться, потому что метод toString
существует дважды, один раз как stati c Integer.toString(someInt)
и один раз как связанный с экземпляром someInteger.toString()
.