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;
.
>Solution :
Animal
is an interface with a single abstract method, eat
. This method does not take any parameters and does not return anything. Because of this, it can represent any function that takes no parameters. For example:
Animal foo = () -> System.out.println("foo");
Now if I call foo.eat()
, it will run the code in the lambda, which prints "foo".
I can also use a method reference instead of a lambda:
Animal foo = SomeClass::someStaticMethod;
Now foo.eat()
will run the parameterless method called someStaticMethod
located in SomeClass
.
Notice that this works in exactly the same way as using the built-in Runnable
interface and called its run
method. Yours is just called Animal
and eat
, rather than Runnable
and run
.
So by the same logic, using a constructor reference of Dog
will invoke the constructor of Dog
.
Animal foo = Dog::new;
Runnable bar = Dog::new;
// these two lines do the same thing:
foo.eat();
bar.run();
Would you still have the confusion if you have written the code with Runnable
instead?
Note that the fact that Dog
implements Animal
does not matter here. Dog
implements Animal
just means that you can do:
Animal animal = new Dog();
which has a completely different meaning. If at this point I do animal.eat()
, then it will output what you expect – "dog eat".
Alternatively, you could also make a method reference to a newly-created Dog
‘s eat
method for it to output "dog eat":
Animal animal = new Dog()::eat;