简体   繁体   English

JavaFX编译警告 - “使用未经检查或不安全的操作” - 原始数据类型?

[英]JavaFX Compilation Warning - “uses unchecked or unsafe operations” - Raw Data Types?

I am learning JavaFX, specifically trying to implement a table using the TableColumn and TableView classes. 我正在学习JavaFX,特别是尝试使用TableColumn和TableView类来实现一个表。 My program compiles without error, but I get an ominous-looking warning at compilation time: 我的程序编译没有错误,但在编译时我收到一个不祥的警告:

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

C:\JavaFX_Sandbox>

This sufficiently weirded me out enough that I haven't had the nerve to try actually running my program. 这足以让我足够强大,以至于我没有勇气尝试实际运行我的程序。 I did some digging here on StackOverflow plus a number of other sites, and discover that the most likely cause of this warning is that I'm using raw data types. 我在StackOverflow和其他一些网站上做了一些挖掘,并发现这个警告的最可能原因是我正在使用原始数据类型。 But if so, I can't spot them. 但如果是这样,我无法发现它们。 And if not, I'm worried what this message could mean. 如果没有,我担心这个消息可能意味着什么。

To describe my program as quickly as possible: I've created a nerdy robot.java class: 尽快描述我的程序:我创建了一个书呆子robot.java类:

public class robot{

    private String name;
    private int intelligence;

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

Nothing fancy. 没有什么花哨。 To store all those robots, I created a robotMgr.java class, essentially a glorified ArrayList to hold them all: 为了存储所有这些机器人,我创建了一个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;
    }
}

(I do more data manipulation in the ArrayList, but the ObservableList is necessary because the TableColumn class expects to be fed the table elements from an ObservableList.) (我在ArrayList中做了更多的数据操作,但是ObservableList是必需的,因为TableColumn类希望从ObservableList中提供表元素。)

Now for the Main Event: A JavaFX program which takes the data above and displays it in a simple, two-column table: 现在为主事件:一个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();

    }
}

All looks good to me. 一切看起来都不错。 And everything compiles fine, except for the warning messages I mentioned above. 除了我上面提到的警告信息之外,一切都编译得很好。 The weird thing is, the message goes away if I comment out the "robotTable.getColumns().addAll(colName, colIntelligenge);" 奇怪的是,如果我注释掉“robotTable.getColumns()。addAll(colName,colIntelligenge);”,消息就会消失。 line only. 只行。

So... I'm completely baffled. 所以......我完全不知所措。 If the error message is warning me about using raw data types, I don't know where they are in my program. 如果错误消息警告我使用原始数据类型,我不知道它们在我的程序中的位置。 And if the error message is warning about something else, I don't know what that might be. 如果错误消息是关于其他事情的警告,我不知道那可能是什么。 Also: why would the addAll() method be the line that causes the warning? 另外:为什么addAll()方法会导致警告? I can't figure that one out for the life for me. 我不能为我的生活找到那个。

Is the issue that the robots' instance variables are all private? 问题是机器人的实例变量都是私有的吗? If so, wouldn't it create a specific syntax error at compilation time? 如果是这样,它不会在编译时创建特定的语法错误吗? Or is the ObservableList the problem? 或者ObservableList是问题吗? In understand that OLs are interfaces, not data structures... but I don't see how this could trip me up here. 理解OL是接口,而不是数据结构...但我不知道这会如何让我在这里绊倒。

If anyone can offer some help or advice, I will be incredibly grateful. 如果有人能提供一些帮助或建议,我将非常感激。

Many thanks! 非常感谢! -RAO -RAO

Your code is perfectly safe to run (it has bugs, which you'll discover when you run it, but those are unrelated to the typesafety about which you're asking). 您的代码运行起来非常安全(它有错误,您在运行它时会发现它们,但这些错误与您提出的类型安全无关)。

Basically, the issue is that the addAll() method you are invoking takes a "varargs" parameter whose type is a generic type. 基本上,问题是您正在调用的addAll()方法采用“varargs”参数,其类型是泛型类型。 For a TableView<S> , TableView.getColumns() returns an ObservableList<TableColumn<S,?>> and the ObservableList<E> addAll() method you are then calling takes a vararg parameter: addAll(E... elements) . 对于TableView<S>TableView.getColumns()返回一个ObservableList<TableColumn<S,?>> ,然后调用的ObservableList<E> addAll()方法接受一个vararg参数: addAll(E... elements) So you end up calling a method with signature addAll(TableColumn<Robot, ?>... columns) . 因此,您最终调用带有签名addAll(TableColumn<Robot, ?>... columns)的方法addAll(TableColumn<Robot, ?>... columns)

Varargs are processed by converting them to an array, so you implicitly create an array of type TableColumn<Robot, ?>[] when you call the addAll method. 通过将Varargs转换为数组来处理Varargs,因此在调用addAll方法时隐式创建TableColumn<Robot, ?>[]类型的数组。 Because arrays and parameterized types do not play well together, the compiler is unable to ensure the type safety of this array. 由于数组和参数化类型不能很好地协同工作,因此编译器无法确保此数组的类型安全性。 Consequently, it issues a warning. 因此,它发出警告。 See, eg here for an example of why the compiler can't ensure type safety here. 见,例如这里为编译器为什么不能在这里确保类型安全的例子。

The authors of the addAll() method probably should have coded it so that it ensured type safety and annotated it so that it avoided this warning (if that's possible: I'd need to think about it for more time than I have right now). addAll()方法的作者可能应该对其进行编码,以便确保类型安全并对其进行注释以避免此警告(如果可能的话:我需要考虑它比现在更多的时间) 。

To avoid the warning, you can simply invoke the add method twice: 要避免警告,您只需调用add方法两次:

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

Alternatively you can create a List of table columns and pass that to the (other) addAll(...) method that takes a collection, instead of a varargs parameter: 或者,您可以创建表列的List ,并将其传递给采用集合的(其他) addAll(...)方法,而不是varargs参数:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM