6

While trying to play with method references, came across a situation where concat method can be used as a BiFunction, as I understand BiFunction apply method requires 2 input arguments and produces a result. Whereas, concat method takes 1 input argument and returns the concatenated string with this value.

Sample code:

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);
  }
}

Output

HelloWorkld
Hello
Workld

Can someone help me understand what happened here?

Himanshu Bhardwaj
  • 4,038
  • 3
  • 17
  • 36
  • 1
    It took `str1`, and `str2`, and called `String#concat(String, String)` on them? You said it yourself, what are you missing? – Rogue Jan 18 '17 at 06:19
  • 1
    Also note strings are immutable, calling concat on them produces a different string object, it won't mutate them (if that was what you were asking) – Rogue Jan 18 '17 at 06:19
  • Nope am not asking about mutation. But I can't seem to String#concat(String, String) this method in String class. Do you have a link. – Himanshu Bhardwaj Jan 18 '17 at 06:20
  • 2
    Ah my bad, it was an implicit operation. `String::concat` operates on two string operands, utilizing the first as the instance. You'll see this with similar operations in streams (e.g. many `#map` calls) – Rogue Jan 18 '17 at 06:51
  • 2
    Yep for eveyone's reference have a look at: http://stackoverflow.com/questions/24816190/odd-syntax-in-api-stringconcat – Himanshu Bhardwaj Jan 18 '17 at 07:23
  • 1
    Possible duplicate of [Odd syntax in API "String::concat"](http://stackoverflow.com/questions/24816190/odd-syntax-in-api-stringconcat) – Didier L Jan 18 '17 at 08:46

2 Answers2

4

The String.concat() method takes two parameters. The first is (implicit) parameter is the String that the method is called on, the second is the explicit argument.

In

str1.concat(str2)

str1 is the implicit argument (within the concat method it can be accessed as this), str2 is the explicit argument.

Or, as explained in the Java Language specification (https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.13.3)

If the form is ReferenceType :: [TypeArguments] Identifier, the body of the invocation method similarly has the effect of a method invocation expression for a compile-time declaration which is the compile-time declaration of the method reference expression. Run-time evaluation of the method invocation expression is as specified in §15.12.4.3, §15.12.4.4, and §15.12.4.5, where:

  • The invocation mode is derived from the compile-time declaration as specified in §15.12.3.

  • If the compile-time declaration is an instance method, then the target reference is the first formal parameter of the invocation method. Otherwise, there is no target reference.

  • If the compile-time declaration is an instance method, then the arguments to the method invocation expression (if any) are the second and subsequent formal parameters of the invocation method. Otherwise, the arguments to the method invocation expression are the formal parameters of the invocation method.

That means, that

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

will get executed as

  "abc".concat("def");
Community
  • 1
  • 1
Thomas Kläger
  • 17,754
  • 3
  • 23
  • 34
  • +1. Not sure why it has been downvoted. But partially it's correct. @Thomas can you expand you answer a bit more to relate with method references and BiFunction. – Himanshu Bhardwaj Jan 18 '17 at 07:25
3

The method reference String::concat represents an instance method reference for a target type whose function takes two String arguements and returns a String. The first arguement will be the receiver of the concat() method and the second arguement will be passed to the concat() method.

Refer Beginning Java8 book for more details of Unbound Receiver. It has exact example explained.

mc20
  • 1,145
  • 1
  • 10
  • 26