I just encountered this "bug", but I'm not sure if this is intended: Code:
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.
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()
". So Swing executes it
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()
". A someMethod()
method that I am executing right now
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. 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
This is not related to Swing, it's what happens when using method references and lambdas behind the scenes.
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; notice that there is no terminal operation for the stream.
来源:https://stackoverflow.com/questions/44543465/why-does-invokelater-execute-in-the-main-thread