61
задан 9 January 2019 в 15:35

4 ответа

Ваш run метод берет Runnable экземпляр, и это объясняет почему run(new R()) работы с R реализация.

R::new не эквивалентно new R(). Это может соответствовать подписи Supplier<Runnable> (или подобные функциональные интерфейсы), но R::new не может использоваться в качестве Runnable реализованный с Вашим R класс.

версия А Вашего run метод, который может взять R::new, мог быть похожим на это (но это будет излишне сложно):

void run(Supplier<Runnable> r) {
    r.get().run();
}

, Почему это компилирует?

, поскольку компилятор может сделать Runnable из вызова конструктора, и это было бы эквивалентно этой версии лямбда-выражения:

new ConstructorRefVsNew().run(() -> {
    new R(); //discarded result, but this is the run() body
});

то же относится к этим операторам:

Runnable runnable = () -> new R();
new ConstructorRefVsNew().run(runnable);
Runnable runnable2 = R::new;
new ConstructorRefVsNew().run(runnable2);

, Но, как можно заметить, Runnable созданный с [1 118], действительно просто звонит new R() в run тело метода.

<час>

А допустимое использование ссылки метода для выполнения R#run могло использовать экземпляр, как это (но Вы будете, конечно, скорее использовать r экземпляр непосредственно, в этом случае):

R r = new R();
new ConstructorRefVsNew().run(r::run);
57
ответ дан 31 October 2019 в 16:04

Первый пример:

new ConstructorRefVsNew().run(R::new);

более или менее эквивалентно:

new ConstructorRefVsNew().run( () -> {new R();} );

эффект - Вы, просто создают экземпляр R, но не называют run метод.

23
ответ дан 31 October 2019 в 16:04

Сравните два вызова:

((Runnable)() -> new R()).run();
new R().run();

((Runnable)() -> new R()) или ((Runnable) R::new), Вы создаете новое Runnable , который ничего не делает <глоток> 1 .

new R(), Вы создаете экземпляр R класс , где run метод четко определен.

<час>

<глоток> <глоток> 1 На самом деле, это создает объект R, который не оказывает влияния на выполнение.

<час>

я думал об обработке 2 вызовов тождественно, не изменяя main метод. Мы должны были бы перегрузиться run(Runnable) с [1 111].

class ConstructorRefVsNew {

    public static void main(String[] args) {
        new ConstructorRefVsNew().run(R::new);
        System.out.println("-----------------------");
        new ConstructorRefVsNew().run(new R());
    }

    void run(Runnable r) {
        r.run();
    }

    void run(Supplier<Runnable> s) {
        run(s.get());
    }

    static class R implements Runnable { ... }
}
10
ответ дан 31 October 2019 в 16:04

run метод ожидает Runnable.

легкий случай new R(). В этом случае Вы знаете, что результатом является объект самого типа R. R, выполнимое, он имеет run метод, и это - то, как Java видит его.

, Но когда Вы передаете R::new, что-то еще происходит. Что Вы говорите, что это должно создать анонимный объект, совместимый с Runnable, чей run метод выполняет операцию, Вы передали его.

операция Вы передали его, не R run метод. Операция является costructor [1 112]. Таким образом это похоже на Вас, передали его анонимный класс как:

new Runnable() {

     public void run() {
         new R();
     }
}

(Не все подробности являются тем же, но это - самая близкая "классическая" конструкция Java).

R::new при вызове, вызовы new R(). Ничто больше, ничто меньше.

7
ответ дан 31 October 2019 в 16:04

Другие вопросы по тегам:

Похожие вопросы: