Java 8: Difference Between Method Reference Bound Receiver and Unbound Receiver

Java 8: Difference between method reference Bound Receiver and UnBound Receiver

The idea of the unBound receiver such as String::length is you're referring to a
method of an object that will be supplied as one of the lambda's parameters. For example,
the lambda expression (String s) -> s.toUpperCase() can be rewritten as String::toUpperCase.

But Bounded refers to a situation when you’re calling a method in a
lambda to an external object that already exists. For example, the lambda expression () -> expensiveTransaction.getValue() can be rewritten as expensiveTransaction::getValue.

Situations for three different ways of method reference

(args) -> ClassName.staticMethod(args)
can be ClassName::staticMethod // This is static (you can think as unBound also)

(arg0, rest) -> arg0.instanceMethod(rest)
can be ClassName::instanceMethod (arg0 is of type ClassName) // This is unBound

(args) -> expr.instanceMethod(args)
can be expr::instanceMethod // This is Bound

Answer retrieved from Java 8 in Action book

Confused with using method reference in Comparator.comparing()

In class Movie, getTitle() is an instance method. It therefore takes one argument, namely an argument of type Movie (the implicit parameter). To call method getTitle(), you need a target object:

movie.getTitle();

Here the object referenced by movie is that one argument.

The function type of getTitle() is thus Movie -> String, which matches the expected functional interface.

Why this functional interface is valid

Method startWith(String str) has only one parameter.

Actually String.startsWith has an implicit this parameter because you’re calling it on an object instance. Thus it conforms to a functional interface with two String parameters.

As mentioned by Giorgi, you should consult the documentation on method references, since there’s a lot more to this syntax, and the way it works when the name before :: refers to an object versus a class name.

Briefly, there are four cases. Assuming a functional interface for a method call with two parameters a and b:

  1. Class::staticMethod

    This is equivalent to (a, b) -> Class.staticMethod(a, b).

  2. object::method

    This is equivalent to (a, b) -> object.method(a, b).

  3. Class::method

    This is equivalent to (a, b) -> a.method(b).

  4. Class::new

    This is equivalent to (a, b) -> new Class(a, b).



Related Topics



Leave a reply



Submit