我正在使用TreeTable,并且在更改单元格工厂时需要传递一个

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

我所在的类(class)是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)而不是“?”同样,但没有任何帮助。

谁能向我解释如何使用此方法?

谢谢。

编辑:

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

使用原始类型回叫有效。但是还有其他解决方法吗?

最佳答案

通配符表示未知类型。

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

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

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

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

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>> {
        ...
    }
}

10-07 20:34