当前位置: 首页 > 面试题库 >

Java泛型“捕获?”

丁鸿云
2023-03-14
问题内容

我正在与一起工作,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)代替“?” 同样,但没有任何帮助。

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

谢谢。

编辑:

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

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


问题答案:

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

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

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

哪里

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

在此,方法调用后,的未知值将?绑定到新类型变量,从而允许shuffle方法引用该类型。T``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>> {
        ...
    }
}


 类似资料:
  • 问题内容: 我查看了Java Generics文档 ,发现了这段代码, 我可以理解,我们正在从中获取一个元素并将其设置为另一个。因此,编译器给出了一个错误。我的问题是,它是有道理的,当2列出了不同即这里列出了和是不同的。但是在上面的示例中,和是相同的列表。为什么编译器不够聪明才能看到呢?实施起来难吗? 编辑 :我知道我可以通过辅助方法或使用代替来修复它。只是想知道为什么编译器不为我做。 问题答案:

  • 问题内容: 阅读Java在线教程,我对通配符捕获一无所知。例如: 为什么编译器无法保留分配的安全性?它知道,例如,通过执行带有整数列表的方法,它可以从i.get中获取一个整数值。因此,它尝试将索引0处的Integer值设置为相同的Integer列表(i)。那么,怎么了?为什么要编写通配符助手? 问题答案: 为什么编译器无法保留分配的安全性? 编译器不知道 任何 关于类型中的元素通过定义。通配符并

  • 在阅读Java在线教程时,我对通配符捕获一无所知。例如:

  • 下面的SCCE显示了实现接口标记的两个类(B和C)。对于实现Marker的每个类,都有一个实现泛型处理程序接口的对应类(B_处理程序、C_处理程序)。映射用于关联Pair的类类型。其次是它的关联处理程序。代码按预期执行;但是,我得到一个编译时警告: 警告:[未检查]未检查的强制转换处理程序h1=(处理程序)(dispatch.get(p1.second.get类()));需要:处理程序找到:处理程

  • 如何获取这个类的类型?对于上下文,我使用ModelMapper,我需要类类型T从S转换为T。 背景: 我已经尝试了N种方法,其中我放置了“//一些方法来获取类型”,但没有任何效果。例如: 或

  • 问题内容: 我有一个代表文本片段的泛型类。该文本片段可能具有多种不同模式(突出显示的不同类型)中的任何一种。这些模式用枚举表示。每个项目的Enum可能不同,但是它必须实现一个接口,该接口提供了一种将其中两个结合的方法(可以突出显示并加粗显示)。所以我有一个界面: 然后我的TextFragment是文本字符串和模式的容器。但是当我尝试声明该类时: 我收到以下错误: 令牌“扩展”的语法错误,预期 根据