Невозможно понять поведение: ссылка на метод с лямбда

Рассмотрим ниже код,

class DemoStatic {
    public static Runnable testStatic() {
        return () -> {
            System.out.println("Run");
        };
    }

    public void runTest () {
        Runnable r = DemoStatic::testStatic;
        r.run();
    }
}

public class MethodReferenceDemo {
    public static void main(String[] args) {
        DemoStatic demo = new DemoStatic();
        demo.runTest();
    }
}

run() метод Runnable экземпляр, который возвращается testStatic метод должен был быть вызван. И вывод на консоль должен быть "Выполнить".

Но этот код не вызывает run() метод экземпляра r и ничего не печатается в консоли.

Может кто-нибудь, пожалуйста, объясните причину.

И прокомментируйте, если я не использую ссылку на метод "::" должным образом.

2 ответа

Решение

Чтобы немного расширить ответ Сотириоса:

Это утверждение:

Runnable r = DemoStatic::testStatic;

эквивалентно

Runnable r = new Runnable() {
    @Override
    public void run() {
        DemoStatic.testStatic();
    }
}

Так r.run() вызывает метод, который вызывает testStatic() вернуть новый Runnable, но потом ничего не делает с этим.

Это

Runnable r = DemoStatic::testStatic;

возвращает Runnable чья run() метод содержит тело метода testStatic()т.е.

public static Runnable testStatic() {
    return () -> {
        System.out.println("Run");
    };
}   

так

r.run();

в основном выполняет

return () -> {
    System.out.println("Run");
};

сбросив return значение.

Это static ссылка на метод. Ссылка на метод означает ваш Runnable ссылается и выполняет метод в методе, который определяет функциональный интерфейс.


Для поведения, которое вы хотите, вы должны сделать

Runnable r = testStatic();
Другие вопросы по тегам