为什么invokeLater会在主线程中执行呢?
Why does invokeLater execute in the main thread?
我刚遇到这个 "bug",但我不确定这是否有意为之:
代码:
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 线程上执行的,但在第二个例子中它不是,尽管我认为它应该是。
这是错误还是有意为之?
在我看来你是个误会
第一行就像在说:"Ok, Swing, what I want you to invokeLater
is someMethod().toString()
"。所以 Swing 执行它
第二行就像在说:"Ok, Swing, what I want you to invokeLater
is the method toString()
of the object returned by the method someMethod()
"。 我现在正在执行的 someMethod()
方法
所以这个结果对我来说是完全合乎逻辑的
请记住,在评估函数之前(在本例中 invokeLater
)Java 需要评估所有参数。所以在第一种情况下Java评估一个lambda函数(不需要执行它)而在第二种情况下它遇到一个方法调用所以它需要执行它
这与 Swing 无关,这是在幕后使用方法引用和 lambda 时发生的情况。
一个更简单的例子:
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
输出;请注意,流没有终端操作。
我刚遇到这个 "bug",但我不确定这是否有意为之: 代码:
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 线程上执行的,但在第二个例子中它不是,尽管我认为它应该是。
这是错误还是有意为之?
在我看来你是个误会
第一行就像在说:"Ok, Swing, what I want you to invokeLater
is someMethod().toString()
"。所以 Swing 执行它
第二行就像在说:"Ok, Swing, what I want you to invokeLater
is the method toString()
of the object returned by the method someMethod()
"。 我现在正在执行的 someMethod()
方法
所以这个结果对我来说是完全合乎逻辑的
请记住,在评估函数之前(在本例中 invokeLater
)Java 需要评估所有参数。所以在第一种情况下Java评估一个lambda函数(不需要执行它)而在第二种情况下它遇到一个方法调用所以它需要执行它
这与 Swing 无关,这是在幕后使用方法引用和 lambda 时发生的情况。
一个更简单的例子:
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
输出;请注意,流没有终端操作。