简体   繁体   English

为什么invokeLater在主线程中执行?

[英]Why does invokeLater execute in the main thread?

I just encountered this "bug", but I'm not sure if this is intended: Code: 我刚刚遇到这个“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
}

In the first example someMethod is being executed on the swing Thread, but in the second example it is not, although it should be in my opinion. 在第一个例子中, someMethod正在swing swing上执行,但在第二个例子中它不是,虽然它应该在我看来。

Is this a bug or is this intended? 这是一个错误还是这个?

To me it seems like a misunderstanding on your side 对我而言,这似乎是对你的误解

The first line is like saying: "Ok, Swing, what I want you to invokeLater is someMethod().toString() ". 第一行就像是说:“好的,Swing,我想让你invokeLatersomeMethod().toString() ”。 So Swing executes it 所以Swing执行它

The second line is like saying: "Ok, Swing, what I want you to invokeLater is the method toString() of the object returned by the method someMethod() ". 第二行好像是说:“好好好,秋千,我要你invokeLater是方法toString()方法返回的对象someMethod() ”。 A someMethod() method that I am executing right now 我正在执行的 someMethod()方法

So the result is completely logical to me 所以结果对我来说完全符合逻辑

Just keep in mind that before evaluating a function (in this case invokeLater ) Java needs to evaluate all arguments. 请记住,在评估函数之前(在本例中为invokeLater ),Java需要评估所有参数。 So in the first case Java evaluate a lambda function (no need to execute it) and in the second case it encounters a method invocation so it needs to execute it 所以在第一种情况下,Java评估一个lambda函数(不需要执行它),在第二种情况下,它遇到一个方法调用, 所以它需要执行它

This is not related to Swing, it's what happens when using method references and lambdas behind the scenes. 不是摇摆有关,它的使用方法引用和lambda表达式幕后时会发生什么。

A simpler example: 一个更简单的例子:

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;
    }
}

You will get a single init output here; 您将在此处获得单个init输出; notice that there is no terminal operation for the stream. 注意流没有终端操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM