This code does not compile with the javac JDK8 compiler.
public class Test extends Application {
public static void main(String[] args) {
launch(Test.class);
}
@Override
public void start(Stage primaryStage) throws Exception {
Service service = new Service() {
@Override
protected Task createTask() {
return null;
}
};
service.setOnFailed(event -> System.out.println(event.getSource().getException().toString()));
}
}
The error is
java: cannot find symbol
symbol: method getException()
location: class java.lang.Object
IntelliJ tells me yet that all is OK and if I manually add a cast on event.getSource()
, the compilation works but Intellij tells me that the cast is redundant.
Is there an Intellij bug ? I use the latest version of Intellij Ultimate (14.1.1).
For this specific case, I would actually write this differently. You already know what the source of the event that is fired is; it's the service
on which you registered the listener. So you can just do
service.setOnFailed(event ->
System.out.println(service.getException().toString());
I can't quite figure out why the compiler can't infer the types from the code you have, but if you properly type the service, providing a parameter for its generic type, then it compiles fine:
import javafx.application.Application;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.stage.Stage;
public class ServiceTest extends Application{
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
Service<Void> service = new Service<Void>() {
@Override
protected Task<Void> createTask() {
return null;
}
};
service.setOnFailed(event ->
System.out.println(event.getSource().getException().toString()));
}
}
There's obviously enough information in your code for the compiler to infer that event
is of type WorkerStateEvent
, which should allow you to call event.getSource().getException()
. I think the type inference just fails for some reason when you use raw types ( Service
) instead of generically-typed objects ( Service<Void>
etc).
The signature of setOnFailed
is
public final void setOnFailed(EventHandler<WorkerStateEvent> value)
So you need to provide an EventHandler<WorkerStateEvent>
. WorkerStatEvent
has the method public Worker getSource()
that returns a javafx.concurrent.Worker
. Your lambda effectively just provides an EventHandler<javafx.event.Event>
. The method getSource()
of javafx.event.Event
just retuns a java.util.EventObject
which does not have the method getException()
that WorkerStateEvent
has.
Use generics:
final EventHandler<WorkerStateEvent> handler = event ->
System.out.println(event.getSource().getException().toString());
service.setOnFailed(handler);
Edit:
Compiling the non-generic version with plain javac
throws the same error:
src/stackoverflowfx/StackOverflowFX.java:29: error: cannot find symbol
final EventHandler handler = event -> System.out.println(event.getSource().getException().toString());
^
symbol: method getException()
location: class Object
Note: src/stackoverflowfx/StackOverflowFX.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error
So this is not an IDE problem.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.