Java泛型"捕获?"

kot*_*ese 21 java generics wildcard capture

我正在和一个工作人员一起工作TreeTable时,我需要通过一个

Callback<TreeTableColumn<A, capture of ?>, TreeTableCell<A, capture of ?>>
Run Code Online (Sandbox Code Playgroud)

A是我正在使用的课程,但我不知道如何处理"捕获?"

我试图创造

new Callback<TreeTableColumn<A, ?>, TreeTableCell<A, ?>>
Run Code Online (Sandbox Code Playgroud)

但IDEA显示出警告

setCellFactory(Callback<TreeTableColumn<A, capture<?>>, TreeTableCell<A, capture<?>>>) in TreeTableColumn cannot be applied to (anonymous Callback<TreeTableColumn<A, ?>, TreeTableCell<A, ?>>)
Run Code Online (Sandbox Code Playgroud)

我尝试使用特定的类(如String)而不是"?" 同样,但没有任何帮助.

谁能向我解释如何使用它?

谢谢.

编辑:

我聚集了一点点信息.该CellFactoryTreeTableColumn<S,T>应该是Callback<TreeTableColumn<S,T>,TreeTableCell<S,T>>但是,我与原始类型创建工作(在库)的TreeTableColumn.

使用原始类型回调有效.但有没有其他选择如何解决这个问题?

mer*_*ike 16

通配符表示一个未知类型.

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

List<?> list = ...;
shuffle(list);
Run Code Online (Sandbox Code Playgroud)

哪里

<T> void shuffle(List<T> list) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

这里,在调用方法时,未知值?绑定到新类型变量,允许shuffle方法引用该类型.Tshuffle

Java编译器通过在匿名类型变量中捕获它来内部表示通配符的值,它称之为"捕获?" (实际上,javac称它们为"捕获#1的?",因为不同的用途?可能引用不同的类型,因此具有不同的捕获).

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

<S,T> setCellFactory(Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> factory);
Run Code Online (Sandbox Code Playgroud)

Callback<TreeTableColumn<S,?>, TreeTableCell<S, ?>> factory;
Run Code Online (Sandbox Code Playgroud)

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

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

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

setCellFactory(newFactory());
Run Code Online (Sandbox Code Playgroud)

哪里

<S,T> Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> newFactory() {
    return new Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)