为什么调用Later在主线程中执行?

我刚刚遇到了这个“错误”,但我不确定这是否是有意的:代码:

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
}

在第一个示例中,它是在 swing Thread 上执行的,但在第二个示例中,它不是,尽管在我看来应该是这样。someMethod

这是一个错误还是故意的?


答案 1

对我来说,这似乎是你这边的误解

第一行就像是说:“好吧,秋千,我想要的是”。所以Swing执行它invokeLatersomeMethod().toString()

第二行就像说:“好吧,Swing,我想要你做的是方法返回的对象的方法”。我现在正在执行的方法invokeLatertoString()someMethod()someMethod()

所以结果对我来说是完全合乎逻辑的

请记住,在评估函数之前(在本例中为),Java需要评估所有参数。因此,在第一种情况下,Java评估lambda函数(无需执行它),在第二种情况下,它遇到方法调用,因此需要执行它invokeLater


答案 2

这与 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


推荐