【问题标题】:JavaFX Compilation Warning - "uses unchecked or unsafe operations" - Raw Data Types?JavaFX 编译警告 - “使用未经检查或不安全的操作” - 原始数据类型?
【发布时间】:2016-04-18 16:16:06
【问题描述】:

我正在学习 JavaFX,特别是尝试使用 TableColumn 和 TableView 类来实现一个表。我的程序编译没有错误,但在编译时我收到了一个看起来不祥的警告:

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

C:\JavaFX_Sandbox>

这足以让我感到很奇怪,以至于我没有勇气尝试实际运行我的程序。我在 StackOverflow 和其他一些网站上做了一些挖掘,发现这个警告最可能的原因是我使用了原始数据类型。但如果是这样,我无法发现它们。如果不是,我担心这条消息可能意味着什么。

为了尽快描述我的程序:我创建了一个 nerdy robots.java 类:

public class robot{

    private String name;
    private int intelligence;

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

没什么特别的。为了存储所有这些机器人,我创建了一个 robotsMgr.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 中获取表元素。)

现在是主赛事:一个 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

【问题讨论】:

  • 那么您是否尝试按照编译器警告所说的那样使用-Xlint:unchecked 进行编译?
  • (我会强烈敦促您开始遵循 Java 命名约定,顺便说一句 - 您的类应该称为 RobotRobotManagerRobotApp。)跨度>
  • 你说得对,乔恩,我需要采用正确的命名约定。信不信由你,但我曾经更糟糕。我正在逐渐吸收这些约定,这需要我几个月的时间......谢谢您的反馈!

标签: java javafx compiler-warnings


【解决方案1】:

您的代码运行起来完全安全(它有错误,您会在运行时发现这些错误,但这些与您询问的类型安全无关)。

基本上,问题在于您正在调用的addAll() 方法采用类型为泛型类型的“varargs”参数。对于TableView&lt;S&gt;TableView.getColumns() 返回ObservableList&lt;TableColumn&lt;S,?&gt;&gt;,然后您调用的ObservableList&lt;E&gt; addAll() 方法采用可变参数:addAll(E... elements)。所以你最终调用了一个带有签名addAll(TableColumn&lt;Robot, ?&gt;... columns)的方法。

可变参数通过将它们转换为数组进行处理,因此当您调用addAll 方法时,您会隐式创建TableColumn&lt;Robot, ?&gt;[] 类型的数组。因为数组和参数化类型不能很好地配合使用,编译器无法保证这个数组的类型安全。因此,它发出警告。见,例如here 举例说明为什么编译器在这里不能确保类型安全。

addAll() 方法的作者可能应该对其进行编码,以确保类型安全并对其进行注释,以避免出现此警告(如果可能的话:我需要花更多的时间来思考它现在)。

为避免警告,您可以简单地调用add 方法两次:

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

或者,您可以创建一个表列的List 并将其传递给采用集合而不是可变参数参数的(其他)addAll(...) 方法:

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

【讨论】:

  • 哇 - 谢谢你,我有很多细节需要挖掘 - 更重要的是,请继续阅读!这非常有用,你不知道。 :)
  • 如果你想完全了解泛型,我推荐 Naftalin 和 Wadler 的“Java Generics and Collections”。
猜你喜欢
  • 1970-01-01
  • 2013-11-24
  • 2019-02-09
  • 2015-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多