Как ссылки на методы работают под капотом, когда есть несколько аргументов - PullRequest
1 голос
/ 05 октября 2019

Как компилятор гарантирует, что эквивалентная лямбда для оператора ниже

BinaryOperator<String> concatOperator = String::concat; 

равна

BinaryOperator<String> concatOperator = (resultString, inputString) -> resultString.concat(inputString);

, а не

BinaryOperator<String> concatOperator = (resultString, inputString) -> inputString.concat(resultString);

Ответы [ 2 ]

5 голосов
/ 05 октября 2019

Это поведение хорошо документировано в JLS

15.13.3. Оценка во время выполнения ссылок на методы

Если объявление времени компиляции является методом экземпляра, то целевой ссылкой является первый формальный параметр метода вызова . В противном случае нет целевой ссылки.

Если объявление времени компиляции является методом экземпляра, то аргументы выражения вызова метода (если есть) являются вторым и последующими формальными параметрами вызоваметод . В противном случае аргументы выражения вызова метода являются формальными параметрами метода вызова.

, и это кажется разумным и интуитивно понятным. Если вы возьмете метод с arity n (n > 2), станет очевидно, что целевой ссылкой должен быть первый параметр, а не последний, а не тот, что в середине.

2 голосов
/ 05 октября 2019

Строка кода, использующая ссылки на методы, классифицируется как типы ссылок на методы как -

Ссылка на метод экземпляра произвольного объекта определенного типа

, где первый лямбда-аргумент выводится как объект типа String, для которого метод с именем concat вызывается со значением параметра, эквивалентным второму лямбда-аргументу. В приведенном выше случае как:

BinaryOperator<String> concatOperator = (result, input) -> result.concat(input);
...