code like this
public class LambdaTest {
public static void main(String[] args) {
final Animal animal = Dog::new;
animal.eat();
}
}
@FunctionalInterface
interface Animal {
void eat();
}
class Dog implements Animal {
public Dog() {
System.out.println("dog init.");
}
@Override
public void eat() {
System.out.println("dog eat");
}
When I ran this code, "dog init." was printed to the console, but "dog eat" was not. Why is that? Can someone tell me the reason?
I expected "dog init" and "dog eat" to be printed, but only "dog init" was printed. Additionally, I'm puzzled as to why there was no error when Animal animal = Dog::new;
.
Animal
is a functional interface with a single methodvoid eat()
(void return, no parameters) – also known as SAM type (single abstract method).It is structurally identical to the
java.util.Runnable
interface (interface Runnable { void run(); }
). Your code could as well be written as:You can assign it any lambda or method reference with zero arguments and no return value, e.g.
() -> {}
.Dog::new
is a method reference and equivalent to the lambda() -> { new Dog(); }
. If you look closely, you will notice that this lambda does not return anything. It constructs a new Dog instance and then forgets about it again.Assigning a method reference or a lambda to a variable does not execute it (yet). You have to explicitly invoke the lambda by calling the named method from your interface.
Now, your
animal
is an instance of yourAnimal
interface and got assigned a method reference which can then be invoked later.animal.eat()
invokes the assigned method reference, calling the constructor.If you want your variable
animal
to hold aDog
instance and then invoke theeat
method on it, call the constructor directly:Animal animal = new Dog();
The "problem" is the signature of your
eat
method, because it is equivalent toRunnable#run
and allows assigning any "empty" action.Lambdas and method references were introduced with Java 8. In Java versions before, you had to create an anonymous class to achieve the same behavior: