2016-04-18 53 views
1

我正在學習JavaFX,專門試圖使用TableColumn和TableView類實現一個表。我的程序編譯沒有錯誤,但我得到一個不祥的前瞻性,在編譯時警告:JavaFX編譯警告 - 「使用未經檢查或不安全的操作」 - 原始數據類型?

C:\JavaFX_Sandbox>javac robotApp.java 
Note: robotApp.java uses unchecked or unsafe operations. 
Note: Recompile with -Xlint:unchecked for details. 

C:\JavaFX_Sandbox> 

這充分weirded我出去,以至於我沒有膽量嘗試實際運行我的程序。我在StackOverflow和其他一些網站上做了一些挖掘,發現這個警告最可能的原因是我使用的是原始數據類型。但如果是這樣,我無法發現它們。如果不是,我擔心這個消息可能意味着什麼。

要儘可能快地描述我的計劃:我創建了一個書呆子robot.java類:

public class robot{ 

    private String name; 
    private int intelligence; 

    public robot(String a, int b){ 
     this.name = a; 
     this.intelligence = b; 
    } 
} 

沒什麼特別的。要保存所有這些機器人,我創建了一個robotMgr.java類,基本上是一個華而不實的ArrayList中保存所有:

import java.util.ArrayList; 
import java.util.List; 
import javafx.collections.*; 

public class robotMgr{ 

    private ArrayList<robot> robotList; 
    private ObservableList<robot> oRobotList; 

    robotMgr(){ 
     robotList = new ArrayList<robot>(); 
     robotList.add(new robot("R2-D2", 7)); 
     robotList.add(new robot("Cylon", 3)); 
     robotList.add(new robot("The Terminator", 5)); 
     robotList.add(new robot("WALL-E", 6)); 
     populateOList(); 
    } 
    public void populateOList(){ 
     for(int i=0; i<robotList.size(); i++) 
      oRobotList.add(robotList.get(i)); 
    } 

    public List<robot> getRobotList(){ 
     return robotList; 
    } 
    public ObservableList<robot> getORobotList(){ 
     return oRobotList; 
    } 
} 

(我在ArrayList中更多的數據操作,但ObservableList是必要的,因爲的TableColumn類預期必須從ObservableList饋送的表元素)

現在的主要事件:A JavaFX的程序,其採用上述的數據並將其顯示在一個簡單的,兩列的表:

import javafx.application.*; 
import javafx.stage.*; 
import javafx.scene.*; 
import javafx.scene.layout.*; 
import javafx.scene.control.*; 
import javafx.scene.control.cell.*; 
import javafx.event.*; 
import javafx.geometry.*; 
import javafx.collections.*; 

public class robotApp extends Application{ 

    public static void main(String[] args){ 
     launch(args); 
    } 

    TableColumn<robot, String> colName; 
    TableColumn<robot, Integer> colIntelligenge; 
    TableView<robot> robotTable; 

    BorderPane borderPane; 
    Scene scene; 
    Stage stage; 

    @Override public void start(Stage primaryStage){ 

     robotMgr myBots = new robotMgr(); 

     colName = new TableColumn<robot, String>("Name"); 
     colName.setMinWidth(100); 
     colName.setCellValueFactory(new PropertyValueFactory<robot, String>("Name")); 
     colIntelligenge = new TableColumn<robot, Integer>("Intelligence"); 
     colIntelligenge.setMinWidth(100); 
     colIntelligenge.setCellValueFactory(new PropertyValueFactory<robot, Integer>("Intelligence")); 

     robotTable = new TableView<robot>(); 
     robotTable.getColumns().addAll(colName, colIntelligenge); 
     robotTable.setItems(myBots.getORobotList()); 

     borderPane = new BorderPane(); 
     borderPane.setCenter(robotTable); 
     scene = new Scene(borderPane, 600, 600); 
     stage = primaryStage; 
     stage.setScene(scene); 
     stage.setTitle("Robot App"); 
     stage.show(); 

    } 
} 

所有外表對我好。除了上面提到的警告信息外,一切都編譯好。奇怪的是,如果我註釋掉「robotTable.getColumns()。addAll(colName,colIntelligenge);」只有線。

所以......我完全感到困惑。如果錯誤消息警告我使用原始數據類型,我不知道它們在我的程序中。如果錯誤信息警告其他事情,我不知道可能是什麼。另外:爲什麼addAll()方法是導致警告的行?我無法爲我的生活找到那一個。

機器人的實例變量是否都是私有的問題?如果是這樣,它不會在編譯時創建特定的語法錯誤嗎?或者是ObservableList的問題?理解OL是接口,而不是數據結構......但我不明白這怎麼能讓我在這裏絆倒。

如果有人可以提供一些幫助或建議,我會非常感激。

非常感謝! -RAO

+3

因此,您是否嘗試使用'-Xlint:unchecked'編譯爲編譯器警告所說的? –

+1

(我會*強烈*敦促你開始遵循Java命名約定,順便說一句 - 你的類應該被稱爲'Robot','RobotManager'和'RobotApp'。) –

+1

[Java命名約定]的鏈接(https:// en .wikipedia.org/wiki/Naming_convention_(編程)#Java) –

回答

4

你的代碼是完全安全的運行(它有錯誤,當你運行它時會發現,但是這些錯誤與你所要求的類型安全無關)。

基本上,問題是您調用的addAll()方法需要一個「varargs」參數,其類型是泛型類型。對於TableView<S>TableView.getColumns()返回ObservableList<TableColumn<S,?>>ObservableList<E>addAll()您正在調用的方法採用可變參數:addAll(E... elements)。所以你最終調用一個簽名爲addAll(TableColumn<Robot, ?>... columns)的方法。

可變參數通過將它們轉換爲數組進行處理,所以當您調用addAll方法時,您隱式創建了一個類型爲TableColumn<Robot, ?>[]的數組。由於數組和參數化類型在一起播放不好,編譯器無法確保此數組的類型安全。因此,它發出警告。參見例如here舉例說明爲什麼編譯器不能確保類型安全。

addAll()方法的作者可能應該對它進行編碼,以確保類型安全並對其進行註釋,以避免此警告(如果可能的話:我需要考慮更多的時間比我有權利現在)。

爲了避免該警告,你可以簡單地調用add方法兩次:

robotTable.getColumns().add(colName); 
robotTable.getColumns().add(colIntelligenge); 

另外,您可以創建表列的List並傳遞到(其他)addAll(...)方法,它需要一個集合,而不是可變參數參數:

robotTable.getColumns().addAll(Arrays.asList(colName, colIntelligence)); 
+0

哇 - 謝謝你,我有很多細節可以挖掘 - 更重要的是,請仔細閱讀!這非常有幫助,你不知道。 :) – Pete

+0

如果你想完全理解泛型,我推薦Naftalin和Wadler的「Java泛型和集合」。 –

相關問題