Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assigning object to interface variable without implementing interface

I was just learning about method refernce concept of java 8.What I found strange is the example where a method reference is assigned to the interface variable without implementing the interface, And calling abstract method of interface is calling the method referenced.

interface Sayable {
    void say();
}

public class InstanceMethodReference {
    public void saySomething() {
        System.out.println("Hello, this is non-static method.");
    }

    public static void main(String[] args) {
        InstanceMethodReference methodReference = new InstanceMethodReference();
        Sayable sayable = methodReference::saySomething;
        sayable.say();
    }
}

Above code prints the message of saySomething method, I am trying to understand how the memory allocation for methods and objects is done here and how overall this works.

Any help appreciated.

like image 431
Bruce_Wayne Avatar asked May 16 '18 09:05

Bruce_Wayne


2 Answers

This is just a syntactic sugar to an anonymous implementation or a lambda with a closure (referring to a state outside of the definition, in your case the instance of methodReference). Method references and lambdas are treated equally with that respect. So the same memory allocation really.

The use of method references (or lambdas) is possible when an interface has only one non-static method and the signature of that method matches that of the lambda or the method reference. In this case the compiler will know how to wrap it and therefore it will be assignable. It does not matter if it is one of "standard" interfaces such as Function, Consumer or Supplier or a custom one, it should be a functional interface that's all.

The following is quoted from the official Oracle Java documentation:

Arrays.sort(rosterAsArray, Person::compareByAge);

The method reference Person::compareByAge is semantically the same as the lambda expression (a, b) -> Person.compareByAge(a, b). Each has the following characteristics:

  • Its formal parameter list is copied from Comparator.compare, which is (Person, Person).
  • Its body calls the method Person.compareByAge.
like image 150
Oleg Sklyar Avatar answered Sep 19 '22 14:09

Oleg Sklyar


While your Sayable does not explicitly declare that it is a @FunctionalInterface, it indeed is one, as it has exactly one non-static method.

Any functional interface can be assigned a lambda-like expression (such as () -> printf("bla bla")) or a method reference (such as methodReference::saySomething). That's it.

like image 30
glglgl Avatar answered Sep 18 '22 14:09

glglgl