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();
}
Interfaces can have default methods with implementation in Java 8 on later. Interfaces can have static methods as well, similar to static methods in classes. Default methods were introduced to provide backward compatibility for old interfaces so that they can have new methods without affecting existing code.
There are several types of a method reference in Java that are allowed in Java 8. Reference to some static methods: The static methods in a code can be referred to from a class. Reference to some instance method of particular objects: Reference to some instance method of an arbitrary object of any particular type.
Java provides a new feature called method reference in Java 8. Method reference is used to refer method of functional interface. It is compact and easy form of lambda expression. Each time when you are using lambda expression to just referring a method, you can replace your lambda expression with method reference.
The interface in Java is a mechanism to achieve abstraction. There can be only abstract methods in the Java interface, not the method body. It is used to achieve abstraction and multiple inheritance in Java. In other words, you can say that interfaces can have abstract methods and variables.
The Supplier
interface has a single (functional) method that:
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With