Functional interface method calling

68 Views Asked by At

Why does this code return no output?

public class Test {
public static Runnable print() {
    return () -> System.out.println("Hello world!!!");
}
public static void main(String[] args) {       
    Runnable r = Test ::print;
    r.run();
}

} This looks correct Runnable r = Test ::print(but Intellij adds warning that print method won't be called). thanks in advance for explanation!

1

There are 1 best solutions below

0
Sweeper On

To be clear, IntelliJ is saying that "Result of 'Test.print()' is ignored", not that print won't be called.

What is the "Result of print"? Well, print returns a Runnable - this:

() -> System.out.println("Hello world!!!")

How did you ignore it? You assigned a method reference of Test::print to a Runnable:

Runnable r = Test::print;

Runnable represents a function that takes no arguments and returns void (i.e. no return value). You are saying that print, which is declared to return a Runnable should be assigned to r, which stores a function that returns nothing. That is clearly ignoring the return value of print.

Note that you are not assigning the return value of print to r, you are assigning the method print itself to r, not calling print at all until r.run().

Assigning the return value of print to r would be written as:

Runnable r = Test.print();

This is not "ignoring the result of print", because you are assigning that result in r.

Let's look at a less confusing example would be:

public static String getString() {
    return "some string";
}

public static void main(String[] args) {
    Runnable r = Test::getString;
    r.run();
}

In the same way, you are saying that getString, which is declared to return a String should be assigned to r, which stores a function that returns nothing. The fact that print returns specifically a Runnable is not relevant to r. All that matters is, print returns something, and r does not return a value, so you are ignoring the return value of print.