Почему не выводит "собака ест"
такой код
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");
}
Когда я запустил этот код, "dog init." было напечатано на консоли, а "dog eat" - нет. Почему это? Может ли кто-нибудь сказать мне причину?
Я ожидал, что будут напечатаны «dog init» и «dog eat», но было напечатано только «dog init». Кроме того, я озадачен тем, почему не было ошибки, когдаAnimal animal = Dog::new;
.
1 ответ
представляет собой интерфейс с одним абстрактным методом, . Этот метод не принимает никаких параметров и ничего не возвращает. Благодаря этому он может представлять любую функцию, не принимающую параметров. Например:
Animal foo = () -> System.out.println("foo");
Теперь, если я вызову , он запустит код в лямбде, который напечатает «foo».
Я также могу использовать ссылку на метод вместо лямбда:
Animal foo = SomeClass::someStaticMethod;
Сейчасfoo.eat()
запустит метод без параметров, называемыйsomeStaticMethod
находится вSomeClass
.
Обратите внимание, что это работает точно так же, как и при использовании встроенногоинтерфейс и вызвал его метод. Ваш просто называется и , а не иrun
.
Таким образом, по той же логике использование ссылки на конструктор вызовет конструктор .
Animal foo = Dog::new;
Runnable bar = Dog::new;
// these two lines do the same thing:
foo.eat();
bar.run();
Будет ли у вас все еще путаница, если вы написали код сRunnable
вместо?
Обратите внимание, что тот факт, что реализует здесь не имеет значения. реализуетAnimal
просто означает, что вы можете сделать:
Animal animal = new Dog();
что имеет совсем другое значение. Если в этот момент я сделаюanimal.eat()
, то он выведет то, что вы ожидаете — «собака ест».
В качестве альтернативы вы также можете сделать ссылку на метод для вновь созданногоDog
хeat
метод для вывода «собака ест»:
Animal animal = new Dog()::eat;