Почему не выводит "собака ест"

такой код

      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;
Другие вопросы по тегам