Подтвердить что ты не робот

Почему invokeLater выполняется в основном потоке?

Я просто столкнулся с этой "ошибкой", но я не уверен, что это предназначено: Код:

public static Object someMethod(){
    assert SwingUtilities.isEventDispatchThread();
    return new Object();
}

public static void main(String[] args){
    SwingUtilities.invokeLater(() -> someMethod().toString());//First Example
    SwingUtilities.invokeLater(someMethod()::toString);//Second Example
}

В первом примере someMethod выполняется в swing Thread, но во втором примере это не так, хотя это должно быть на мой взгляд.

Является ли это ошибкой или это предназначено?

4b9b3361

Ответ 1

Мне кажется, что непонимание на вашей стороне

Первая строка похожа на высказывание: "Ок, Swing, я хочу, чтобы вы invokeLater были someMethod().toString()". Итак, Swing выполняет его

Вторая строка похожа на высказывание: "Хорошо, Swing, я хочу, чтобы вы invokeLater - это метод toString() объекта, возвращаемого методом someMethod()". A someMethod(), который выполняется прямо сейчас

Итак, результат полностью логичен мне

Просто имейте в виду, что перед оценкой функции (в данном случае invokeLater) Java необходимо оценить все аргументы. Поэтому в первом случае Java оценивает лямбда-функцию (ее не нужно выполнять), а во втором случае она встречает вызов метода , поэтому ему нужно выполнить его

Ответ 2

Это не связано с Swing, это то, что происходит при использовании ссылок на методы и лямбда за кулисами.

Простейший пример:

public static void main(String[] args) {
    Stream.of(1, 2, 3).map(initMapper()::inc);

    Stream.of(1, 2, 3).map(x -> initMapper().inc(x));
}

private static Mapper initMapper() {
    System.out.println("init");
    return new Mapper();
}

static class Mapper {

    public int inc(int x) {
        return x + 1;
    }
}

Здесь вы получите один вывод init; обратите внимание, что для потока нет терминальной операции.