Почему 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, но во втором примере это не так, хотя это должно быть на мой взгляд.
Является ли это ошибкой или это предназначено?
Ответы
Ответ 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
; обратите внимание, что для потока нет терминальной операции.