【问题标题】:Why does invokeLater execute in the main thread?为什么invokeLater在主线程中执行?
【发布时间】:2017-06-14 11:26:58
【问题描述】:

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

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 上执行,但在第二个示例中不是,尽管我认为应该如此。

这是一个错误还是有意为之?

【问题讨论】:

  • 看起来方法引用需要适当的对象或类作为第一个参数,而不是某种获取它的方法,因此在主线程中调用方法会破坏断言。没有方法的断言结果将用于创建methodResult::toString,它相当于()->methodResult.toString()
  • 错误在哪里?在第二次调用中,someMethod() 本身在main 主体中进行评估(因此,在main 线程中),然后将对结果对象的toString 方法的引用传递给invokeLater

标签: java multithreading lambda java-8 method-reference


【解决方案1】:

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

第一行就像是在说:“好的,Swing,我想让你invokeLatersomeMethod().toString()”。所以 Swing 执行它

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

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

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

【讨论】:

  • 那么问题来了:为什么java不允许SwingUtilities.invokeLater(this::someMethod().toString);这样的语句?
  • 你在这里犯了几个错误。请注意,您不能在静态上下文中使用 this。此外,如果您使用方法引用,则不要将() 放在方法名称之后(因此它将是this::someMethod)。最后,Java 8 允许方法引用,但您尝试使用的是在方法引用的结果对象上调用方法(这是不允许的)
  • 总结一下,如果您需要调用多个方法,则需要一个 lambda 函数
  • @RoiEX 因为正确的语法是this.someMethod()::toString
  • @immibis this.someMethod()::toStringsomeMethod()::toString 一样正确。 this 是隐含的,所以如果你添加它只是为了冗长
【解决方案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 输出;注意流没有终端操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多