原始类型、无界通配符和在泛型中使用 Object 之间有什么区别

2022-09-01 19:09:50

我正在阅读关于有效Java中的泛型的章节。

帮助我了解 、 和 ? 之间的区别。SetSet<?>Set<Object>

以下段落摘自该书。

作为快速查看,是表示可以包含任何类型对象的集合的参数化类型,是表示只能包含某些未知类型的对象的集合的通配符类型,并且是选择退出泛型类型系统的原始类型。Set<Object>Set<?>Set

“某种未知类型”是什么意思?都是未知类型的类型吗?在这种情况下,和 之间的具体区别是什么?ObjectSet<?>Set<Object>


答案 1
  • 原始类型 () 将该类型视为根本没有泛型类型信息。请注意一个微妙的影响,即不仅类型参数将被忽略,而且该类型的方法可能具有的所有其他类型参数也会被忽略。您可以向其添加任何值,它将始终返回 。SetTObject
  • Set<Object>是接受所有对象(即所有对象)并将返回类型对象的 。SetObjectObject
  • Set<?>是 接受某种特定但未知类型的所有对象,并将返回该类型的对象。由于对此类型一无所知,因此您无法向该集合添加任何内容(除了 ),并且您唯一知道的有关它返回的值的是它们是 的某种子类型。SetnullObject

答案 2

在运行时,JVM 将只看到类型擦除。Set

在编译时,有一个区别:

Set<Object>参数化类型,因此,将参数化为 。EObjectSet.add(E element)Set.add(Object element)

Set<?>另一方面,在类型上添加通配符,因此转换为 。由于这是不可编译的,因此java将其“翻译”为。这意味着您无法向该集添加任何内容(空值除外)。原因是通配符引用了未知类型。ESet.add(E element)Set.add(? element)Set.add(null element)


推荐