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

Viewed 7522

I am trying to use Java 8 method references in my code. There are four types of method references available.

  1. Static method reference.
  2. Instance Method (Bound receiver).
  3. Instance Method (UnBound receiver).
  4. Constructor reference.

With Static method reference and Constructor reference i have no problem, but Instance Method (Bound receiver) and Instance Method (UnBound receiver) really confused me. In Bound receiver, we are using an Object reference variable for calling a method like:

objectRef::Instance Method

In UnBound receiver we are using Class name for calling a method like:

ClassName::Instance Method.

I have the following question:

  1. What is the need for different types of method references for Instance Methods?
  2. What is the difference between Bound and Unbound receiver method references?
  3. Where should we use Bound receiver and where should we use Unbound receiver?

I also found the explanation of Bound and Unbound receiver from Java 8 language features books, but was still confused with the actual concept.

6 Answers

I've captured this from a recent presentation

enter image description here

Here's an example:

public static void main(String[] args) {
    // unbound
    UnaryOperator<String> u = String::toUpperCase;
    System.out.println(u.apply("hello"));

    // bound
    String a = "hello";
    Supplier<String> r = a::toUpperCase;
    System.out.println(r.get());
}

which will output two lines of HELLO.

Along with the excellent answers from above. Thanks to the wonderful explanation by joshua bloch, effective java third edition. I was finally able to wrap my head around what bounded and unbounded reference means.

In bounded reference, the receiving object is specified in the method reference. Bound references are similar in nature to static references: the function object takes the same arguments as the referenced method.

In unbound references, the receiving object is specified when the function object is applied, via an additional parameter before the method’s declared parameters. Unbound references are often used as mapping and filter functions in stream pipelines

Finally, there are two kinds of constructor references, for classes and arrays. Constructor references serve as factory objects.

`Method Ref    |     Example                   |    Lambda Equivalent
  Static       |   Integer::parseInt           |   str -> Integer.parseInt(str)
  Bound        |   Instant.now()::isAfter      |   Instant then = Instant.now(); 
                                               |   t -> then.isAfter(t)
  Unbound      |  String::toLowerCase          |   str -> str.toLowerCase()
  Class 
Constructor    |  TreeMap<K,V>::new            |   () -> new TreeMap
  Array 
Constructor    |   int[]::new                  |  len -> new int[len]`
Related