2017-01-18 4 views
3

При попытке воспроизвести ссылки на методы столкнулся с ситуацией, когда метод concat может использоваться как BiFunction, так как я понимаю, что метод BiFunction apply требует 2 входных аргумента и дает результат. Принимая во внимание, что метод concat принимает 1 входной аргумент и возвращает конкатенированную строку с этим значением.String.concat используется как функция BiFunction

Пример кода:

public class Test { 
    public static void main(String[] args) { 
    Test t = new Test(); 
    String str1 = "Hello"; 
    String str2 = "Workld"; 
    System.out.println(t.stringManipulator(str1, str2, String::concat)); 
    System.out.println(str1); 
    System.out.println(str2); 
    } 
    private String stringManipulator(String inputStr, String inputStr2, BiFunction<String, String, String> function) { 
    return function.apply(inputStr, inputStr2); 
    } 
} 

Выход

HelloWorkld 
Hello 
Workld 

Может кто-то помочь мне понять, что здесь произошло?

+1

Для этого потребовались 'str1' и' str2' и назывались 'String # concat (String, String)' на них? Вы сами это сказали, чего не хватает? – Rogue

+1

Также обратите внимание, что строки неизменяемы, вызов concat на них создает другой строковый объект, он не будет мутировать их (если это было то, что вы просили) – Rogue

+0

Нет, я не спрашиваю о мутации. Но я не могу представить String # concat (String, String) этот метод в классе String. У вас есть ссылка. –

ответ

2

Метод эталонного String::concat представляет собой метод экземпляра ссылки для целевого типа функция которого принимает два String аргументы и возвращает String.Первым аргументом будет приемник метода concat(), а второй аргумент будет передан методу concat().

См Beginning Java8 book для более подробной информации о Unbound приемника. Он поясняет пример.

+0

Спасибо, что страница прояснила проблему. –

1

Метод String.concat() принимает два параметра. Первым (неявным) параметром является String, вызываемый методом, второй - явным аргументом.

В

str1.concat(str2) 

str1 является неявным аргументом (в пределах concat метода можно получить доступ, как this), str2 является явным аргументом.

Или, как описано в спецификации Java Language (https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.13.3)

Если форма ReferenceType :: [TypeArguments] Идентификатор, тело метода вызова аналогично имеет эффект выражения вызова метода для объявление времени компиляции, которое является объявлением времени компиляции ссылочного выражения метода. Во время выполнения вычисления выражения вызова метода является таким, как определено в §15.12.4.3, §15.12.4.4 и §15.12.4.5, где:

  • Режим вызова является производным от декларации во время компиляции, как указанных в п. 15.12.3.

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

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

Это означает, что

BiFunction<String, String, String> function = String::concat; 
    function.apply("abc", "def"); 

будет выполнен, как

"abc".concat("def"); 
+0

+1. Не уверен, почему он был опущен. Но отчасти это правильно. @Thomas вы можете расширить ваш ответ немного больше, чтобы связать с ссылками методов и BiFunction. –

 Смежные вопросы

  • Нет связанных вопросов^_^