2015-04-05 38 views
1

此代碼不能用javac JDK8編譯器編譯。編譯JavaFX WorkerStateEvent上的lambda時出錯

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

的錯誤是

java: cannot find symbol 
symbol: method getException() 
location: class java.lang.Object 

的IntelliJ告訴我呢,一切都OK,如果我手動添加投上event.getSource(),彙編作品的IntelliJ卻告訴我,中投是多餘的。

是否有Intellij錯誤?我使用最新版本的Intellij Ultimate(14.1.1)。

回答

2

對於這個特定的情況,我實際上寫這個不同。你已經知道被解僱的事件的來源是什麼;這是您註冊偵聽器的service。所以,你可以做

service.setOnFailed(event -> 
     System.out.println(service.getException().toString()); 

我不能完全弄清楚爲什麼編譯器不能從你的代碼推斷類型,但如果你正確地鍵入服務,爲它的通用類型的參數,然後它編譯罰款:

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

} 

有明顯的代碼足夠的信息讓編譯器推斷eventWorkerStateEvent類型,它應該讓你打電話event.getSource().getException()的。我認爲當你使用原始類型(Service)而不是一般類型的對象(Service<Void>等)時,類型推斷失敗了。

+0

謝謝,但問題是更多關於lambda如何與泛型一起工作以及爲什麼intellij沒有檢測到這個編譯階段之前的錯誤。我能夠單獨糾正這一點。 – mfalaize 2015-04-05 18:45:06

+1

是的,只是提供一個替代方案。儘管你的原始代碼編譯,所以這是一個IntelliJ錯誤。 – 2015-04-05 18:47:31

+0

什麼?你說我發佈的代碼片段編譯?我雖然在自動完成的錯誤... – mfalaize 2015-04-05 18:54:41

1

setOnFailed簽名是

public final void setOnFailed(EventHandler<WorkerStateEvent> value) 

所以,你需要提供一個EventHandler<WorkerStateEvent>WorkerStatEvent的方法public Worker getSource()返回javafx.concurrent.Worker。您的lambda有效提供EventHandler<javafx.event.Event>。方法getSource()javafx.event.Event只是回調一個java.util.EventObject,它不具有WorkerStateEvent具有的方法getException()

使用泛型:

final EventHandler<WorkerStateEvent> handler = event -> 
    System.out.println(event.getSource().getException().toString()); 
service.setOnFailed(handler); 

編輯:

編譯非通用版本與普通javac拋出了同樣的錯誤:

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 

所以這不是一個IDE問題。

+0

嗯,所以看起來Intellij在這一點上是一個小錯誤,因爲自動完成適用於'getException()'... – mfalaize 2015-04-05 18:41:14