Can Java 8 implement interface on the fly for method reference?

4.1k Views Asked by At

I learn new features of Java 8.

I am playing with different examples and I have found a strange behaviour:

public static void main(String[] args) {       
    method(Test::new);
}
static class Test{
}

private static void method(Supplier<Test> testSupplier){
    Test test = testSupplier.get();
}

This code compiles successfully but I have no idea how it works.

Why is Test::new acceptable as Supplier?

Supplier interface looks very simple:

@FunctionalInterface
public interface Supplier<T> {    
    T get();
}
3

There are 3 best solutions below

1
On BEST ANSWER

The Supplier interface has a single (functional) method that:

  • does not take any parameters;
  • returns an object.

Therefore, any method that comply with those two points, comply with the functional contract of Supplier (because the methods will have the same signature).

Here, the method in question is a method reference. It takes no parameters and returns a new instance of Test. You could rewrite it to:

method(() -> new Test());

Test::new in syntactic sugar for this lambda expression.

0
On

It might be a Function, rather than a supplier, if an argument is required. But method references can refer to constructors in the same way they refer to methods; they just have a funny name (new).

From the Java Tutorial, there are four kinds of method references:

Kind                              Example
-------------------------------   ------------------------------------
Reference to a static method      ContainingClass::staticMethodName
Reference to an instance method   containingObject::instanceMethodName
of a particular object  
Reference to an instance method   ContainingType::methodName
of an arbitrary object of a 
particular type
Reference to a constructor        ClassName::new
2
On

Test::new is a method reference. Rather than adding a new explanation it's worth taking a look at the tutorial for method references as it explains them pretty well.

The direct answer to your question is that Supplier is a functional interface - meaning that it has a single non-default method. The constructor for Test has exactly the same signature (no arguments, returns Test) and so can be directly referenced to create an anonymous Supplier.

There are four flavours of method references: check out the tutorial to understand them all.