3

Here is an example I ran across while studying the functional interface concept.

interface Sayable{  
   void say();  
}  
public class MethodReference {  
    public static void saySomething(){  
        System.out.println("Hello, this is static method.");  
    }  
    public static void main(String[] args) {  
        // Referring static method  
        Sayable sayable = MethodReference::saySomething;  
        // Calling interface method  
        sayable.say();  
    }  
} 

This is printing "Hello, this is static method." in output when it runs. My question how it is printing the output when we call the say() method( which is not implemented)

Naman
  • 27,789
  • 26
  • 218
  • 353
mallikarjun
  • 1,862
  • 5
  • 23
  • 47
  • 5
    It **is** implemented. `MethodReference::saySomething` is an instance of Sayable whose `say()` method is implemented by the method `saySomething`. https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html – JB Nizet May 01 '19 at 06:58
  • 1
    I swear the very first time I looked at this in 2014, I had the same feeling you do now; but you get used to it while reading the documentation a lot more – Eugene May 01 '19 at 07:04
  • 1
    You just have to take Java's word for it all. `Sayable` defines as a type a function that takes no arguments and returns no value because Java says so. Since that's what `MethodReference::saySomething` is, you can assign it to a reference of that type. Then there's what you do with such a reference. Having an arbitrary method name to call to invoke that function really is weird. You just have to go with it. – CryptoFool May 01 '19 at 08:35
  • @JBNizet and all Thanks will accepting the given answer – mallikarjun May 01 '19 at 10:50

2 Answers2

3

You can think of the method reference like this:

Sayable sayable = new Sayable() {

    @Override
    void say() {
        // Grab the body of the method referenced by the method reference,
        // which is the following:
        System.out.println("Hello, this is static method.");
    }
}

The method reference is valid because

  • the target type is the functional interface Sayable (you're trying to store the result into a Sayable type); and
  • the signature of the method reference to saySomething() matches the functional interface method say(), that is, the parameters and the return type match1.

The implementation of the say() method of the Sayable instance referred to as the variable sayable equals the body of the method the method reference refers to.

So like JB Nizet says in the comments, say() actually is implemented.


1 A little detail: the word 'match' does not exactly mean 'are equal'. E.g. if saySomething() returned an int, it would still work, although the target type's only method defines the return type to be void.

MC Emperor
  • 22,334
  • 15
  • 80
  • 130
0

Basically an interface with only one abstract method is Functional interface.

If you want to create interface object anonymously and call saySomething() of MethodReference. In normal way it will be like this..

Sayable sayable = new Sayable() {
  @Override
    void say() {
       MethodReference::saySomething;  
    }
}

In case of functional interface , as there is always going to be only one method. You can ignore the say() and related braces -this is provided by lambdas.

So you can say .

Sayable sayable = MethodReference::saySomething;  

This is only for Functional interfaces. Not for interfaces with multiple abstract methods.

Arasn
  • 138
  • 10