Java 泛型 “捕获 ?

2022-09-01 02:42:06

我正在与一个合作,当更换电池工厂时,我需要通过一个TreeTable

Callback<TreeTableColumn<A, capture of ?>, TreeTableCell<A, capture of ?>>

其中A是我正在使用的类,但我不知道如何使用“捕获?

我试图创造

new Callback<TreeTableColumn<A, ?>, TreeTableCell<A, ?>>

但 IDEA 显示警告

setCellFactory(Callback<TreeTableColumn<A, capture<?>>, TreeTableCell<A, capture<?>>>) in TreeTableColumn cannot be applied to (anonymous Callback<TreeTableColumn<A, ?>, TreeTableCell<A, ?>>)

我尝试使用特定的类(如String)而不是“?”,但没有任何帮助。

任何人都可以向我解释如何使用这个?

谢谢。

编辑:

我收集了更多的信息。但是,应该,我正在使用的 TreeTableColumn 是作为原始类型(在库中)创建的。CellFactoryTreeTableColumn<S,T>Callback<TreeTableColumn<S,T>TreeTableCell<S,T>>

使用原始类型回调是有效的。但是,还有其他选择如何解决这个问题吗?


答案 1

通配符表示未知类型。

通配符捕获是将通配符类型的值绑定到新类型变量的过程。例如:

List<?> list = ...;
shuffle(list);

哪里

<T> void shuffle(List<T> list) {
    ...
}

此处,在调用方法时,未知值绑定到新的类型变量,从而允许 shuffle 方法引用该类型。?Tshuffle

Java 编译器通过在匿名类型变量中捕获通配符的值来内部表示通配符的值,该变量称为“捕获?(实际上,javac称它们为“捕获#1的?”,因为不同的用法可能指的是不同的类型,因此有不同的捕获)。?

好吧,那么你的代码中有什么问题呢?您正在尝试调用方法

<S,T> setCellFactory(Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> factory);

Callback<TreeTableColumn<S,?>, TreeTableCell<S, ?>> factory;

在方法签名中,类型参数 T 代表必须由调用方提供的单个类型。为方便起见,编译器会自动尝试推断合适的值 (->类型推断)。编译错误意味着编译器无法执行此操作。

在这种情况下,这不是类型推断的缺点,因为实际上不可能为分配合适的值,因为两者都需要是的子类型,但编译器无法知道两者代表同一类型,甚至相关类型。T?T?

若要成功调用此方法,参数类型必须对所有出现的 T 使用相同的类型。如果您手头已经有了这样的类型,请继续使用它。否则,您可以使用通配符捕获引入一个:

setCellFactory(newFactory());

哪里

<S,T> Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> newFactory() {
    return new Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> {
        ...
    }
}

答案 2

从我从什么是捕获转换oracle捕获通用文档中发现的,看起来你遇到了一些问题,编译器找不到所需的帮助器类,或者试图将Object放在那里,但你给他的东西不能安全地转换。

编辑:

DEFAULT_CELL_FACTORY

public static final Callback<TreeTableColumn<?,?>,TreeTableCell<?,?>>

如果在 TreeTableColumn 实例上未指定 cellFactory,则默认情况下将使用此单元格生成器。目前,如果 Item 是 Node,它只是在图形属性中呈现 TableCell item 属性,或者如果 Item 不为 null,它只是调用 string(),在 text 属性内设置结果字符串。

setCellFactory

public final void setCellFactory(Callback<TreeTableColumn<S,T>,TreeTableCell<S,T>> value)

设置属性单元格“网站”的值。属性说明:此列中所有单元格的单元格工厂。单元工厂负责为单个树表列呈现每个 TreeTableCell 中包含的数据。默认情况下,TreeTableColumn 使用默认的单元工厂,但可以将其替换为自定义实现,例如,以不同的方式显示数据或支持编辑。有很多关于在其他地方创建自定义单元工厂的文档(例如,请参阅Cell和TreeTableView)。

最后,javafx.scene.control.cell 包中提供了许多预构建的单元工厂。

取自 Java 8 API Doc

所以像这样的东西应该朝着正确的方向前进:

public static <S> Callback<TableColumn<S,String>, TableCell<S,String>> forTableColumn() {
   return forTableColumn(new DefaultStringConverter());
}

或类似的东西,这取决于你想给细胞什么。

setCellFactory(TextFieldTableCell.<DataModel, Integer>forTableColumn(new IntegerStringConverter()));

这些代码片段取自此堆栈溢出线程

最后这个链接也可以帮助你: 表视图单元格教程

因此,这应该让您在黑暗中更多地了解可能导致问题的原因。


推荐