为什么在声明类型参数时,JavaFXML TablePosition 实例被视为原始类型?



以下代码与我正在开发的相当复杂的会计应用程序隔离,但编译器警告与编译应用程序时返回的警告完全相同。应用程序所需的一些逻辑是确保 TableView 的视区以特定事务开头。

package tabpane2.view;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableView;
import newdawn.model.TxnObject;
public class MainController implements Initializable {
@FXML private Button exitBtn;
@FXML private Button goBtn;
@FXML private TableView<TxnObject> txnTable;
@FXML private TableColumn<TxnObject, String> txnDateCol;
@FXML private TableColumn<TxnObject, String> toFromCol;
private ObservableList<TxnObject> txnData = FXCollections.observableArrayList(); 

@Override
public void initialize(URL location, ResourceBundle resources) {
txnDateCol.setCellValueFactory(cellData -> cellData.getValue().localtxnDateProperty());
toFromCol.setCellValueFactory(cellData -> cellData.getValue().toFromProperty());
setTableView();
txnTable.setItems(txnData);
}
private void getTablePosition() { 
ObservableList<TablePosition> rowvals  = txnTable.getSelectionModel().getSelectedCells();
for (int i = 0; i < rowvals.size(); i++) {
TablePosition pos = txnTable.getSelectionModel().getSelectedCells().get(i);
int row = pos.getRow();
TxnObject obj = txnTable.getItems().get(row);
System.out.println("Txn is " + obj.toString());
}
}
private void setTableView(){
txnData.add(new TxnObject("19000101","001","Fred","B","C","D","0.00","0.00","0.00"));
txnData.add(new TxnObject("19000102","001","Lars","B","C","D","0.00","0.00","0.00"));
txnData.add(new TxnObject("19000102","002","Bertil","B","C","D","0.00","0.00","0.00"));
}
@FXML private void handleGoBtn() {
getTablePosition();
}
@FXML private void handleExitBtn() {
System.exit(0);
}
}

返回的转储如下所示:

G:J2EETabPane_2srctabpane2viewMainController.java:33: warning: [rawtypes] found raw type: TablePosition
ObservableList<TablePosition> rowvals  = txnTable.getSelectionModel().getSelectedCells();
missing type arguments for generic class TablePosition<S,T>
where S,T are type-variables:
S extends Object declared in class TablePosition
T extends Object declared in class TablePosition
G:J2EETabPane_2srctabpane2viewMainController.java:35: warning: [rawtypes] found raw type: TablePosition
TablePosition pos = txnTable.getSelectionModel().getSelectedCells().get(i);
missing type arguments for generic class TablePosition<S,T>
where S,T are type-variables:
S extends Object declared in class TablePosition
T extends Object declared in class TablePosition

阅读转储时,它说TablePosition需要两个类型参数,即 S 和 T。所以我尝试将pos声明替换为:

TablePosition<TxnObject, TxnObject> pos = txnTable.getSelectionModel().getSelectedCells().get(i);

并且还尝试过:

TablePosition<TxnObject, String> pos = txnTable.getSelectionModel().getSelectedCells().get(i);

但编译随后返回:

G:J2EETabPane_2srctabpane2viewMainController.java:33: warning: [rawtypes] found raw type: TablePosition
ObservableList<TablePosition> rowvals  = txnTable.getSelectionModel().getSelectedCells();
missing type arguments for generic class TablePosition<S,T>
where S,T are type-variables:
S extends Object declared in class TablePosition
T extends Object declared in class TablePosition
G:J2EETabPane_2srctabpane2viewMainController.java:36: warning: [unchecked] unchecked conversion
TablePosition<TxnObject, TxnObject> pos = txnTable.getSelectionModel().getSelectedCells().get(i);
required: TablePosition<TxnObject,TxnObject>
found:    TablePosition

required: TablePosition<TxnObject,String>
found:    TablePosition

我不明白为什么发出警告,即使我给了TablePosition它要求的论点。我做错了什么?

这是一个错误,或者,如果设计实际上是有意的,则是 API 签名的结果。如果您查看TableViewSelectionModel#getSelectedCells()方法,您会发现它返回一个ObservableList<TablePosition>。如您所见,该列表声明了原始类型的TablePosition,这有效地擦除了与TableView一起使用的通用信息。如果在没有原始类型的情况下实现它,则该方法将改为返回ObservableList<TablePosition<S, ?>>

您尝试通过(隐式(强制转换为泛型类型来解决此问题,但从原始类型到泛型类型是未经检查的操作,因此会出现警告。

有一个与此问题相关的错误报告:JDK-8089446。但是,根据注释,修复错误可能不向后兼容,因此错误可能永远无法修复。请注意,不仅上述内容存在此问题,TableViewFocusModel#focusedCell属性也是如此;有一个增强请求,JDK-8212737,但修复该问题具有与向后兼容性相同的潜在问题。

不幸的是,除了抑制警告之外,您无能为力。如果这是整个应用程序中的问题,则可以创建一个实用工具来"还原"一般信息:

@SuppressWarnings("unchecked")
public static <S> ObservableList<TablePosition<S, ?>> getSelectedCells(TableView<S> table) {
return (ObservableList<TablePosition<S, ?>>)
(ObservableList<?>) table.getSelectionModel().getSelectedCells();
}

请注意,TablePosition<S, ?>的第二个类型参数是通配符(即?(。这是必需的,因为表视图中的每个表列都能够保存不同的任意类型。

最新更新