多级通配符是什么?语法混淆。

6
我正在阅读来自AngelikaLangerGenericsFaq的多级通配符。我对语法感到非常困惑。该文档表示:

类型 Collection<Pair<String,?>> 是泛型 Collection 接口的具体实例化。它是一个异构的集合,包含不同类型的一对键值对。它可以包含类型为 Pair<String,Long>Pair<String,Date>Pair<String,Object>Pair<String,String> 等等元素。换句话说,Collection<Pair<String,?>> 包含了不同类型的一对键值对,形式为 Pair<String,?>

类型 Collection<? extends Pair<String,?>> 是一个通配符参数化类型;它不代表一个具体的参数化类型。它代表来自 Collection 接口实例化家族的代表,其中类型参数是 Pair<String,?> 的形式。兼容的实例化有 Collection<Pair<String,Long>>Collection<Pair<String,String>>Collection<Pair<String,Object>>Collection<Pair<String,?>>。换句话说,我们不知道它代表哪个 Collection 实例化。

作为一个经验法则,你需要自上而下阅读多级通配符。

我对以下几点感到困惑:

  1. 有人能否举例详细解释这三个引用语的含义,因为我完全不懂它们的语法。
  2. 文档中说,para-1是通用类型的具体实例化,而其他则不是具体实例化?这是怎么回事?
  3. “自上而下”读取通配符是什么意思?
  4. 多级通配符的优势是什么?

有人能够详细解释这些问题吗?谢谢。

2个回答

11
有人能够举例详细解释这三个引用吗?我对语法完全感到困惑。
好的,将这3个引用再次写在这里是没有意义的,因为我无法给出比这更好的解释。相反,我会尝试回答你下面的问题,然后可能你也会理解这个问题的答案。如果不行,你可以再次提问,我会尽量进一步阐述。
文档说,para-1 是泛型类型的具体实例化,而其他的则不是具体实例化吗?这是怎么回事?
具体实例化是指所有类型参数都是具体类型,并在编译时已知的情况。例如,List 是具体实例化,因为String是一个具体类型。它的类型在编译时已知。而List 不是具体类型,因为? extends Number 可以是任何扩展Number的类型。所以它的类型在编译时是未知的。同样,Map 是泛型类型Map 的一个具体实例化。
在多层类型参数的情况下,如List>,外部的List是List的具体实例化,因为元素的类型在编译时已知是List,尽管内部的List是通配符实例化,因为存储的元素类型可以是Integer、Double等Number的任何子类。但是该段落仅讨论了外部类型。外部类型只能包含List类型。
这就是为什么第一段说它是一组异构的Pair,因为Pair的实际类型参数可以是任何东西,但肯定是Pair而不是其他类型。什么是自上而下地阅读通配符? 通俗的说,它意味着从左到右。在确定参数化类型的类型时,您首先看到最外层的类型参数。然后,如果该类型参数本身是一个参数化类型,则移动到该参数化类型的类型参数。因此,我们从左到右阅读类型参数。
多级通配符的优点是什么? 假设您想创建一个“水果列表的列表”。现在,您的内部“列表”可以包含任何种类的水果。“苹果”也是一种“水果”,“香蕉”也是一种“水果”。因此,您必须确保您获得所有这些水果。由于泛型类型是不变的,即“List ”与“List ”不同,如果您的列表类型为“List >”,则无法添加“List ”。为此,您需要使用通配符,如“List >”,它现在可以采用“List ”、“List ”或任何水果列表。

感谢Rohit提供如此详细的解释。让我们看看Collection<Pair<String,?>>,它确实包含通配符符号,那么它如何可以成为具体类型,编译器不知道另一种类型是什么。那我们怎么称它为具体类型呢? - benz
1
@benz,我刚刚添加了一个解释。请检查编辑。 - Rohit Jain
很棒的解释,Rohit。谢谢你。我在同一主题上还有一些疑问,我会完成并编辑问题,因为将它们添加到这里非常相关。 - benz
@benz。好的。但是如果疑问与同一问题无关,则可以考虑将其发布为不同的问题。 - Rohit Jain
我一定会做到的。 - benz

-1

带通配符的泛型实际上是“存在类型”。如果您对逻辑有所了解,您可以将G< ? extends T >读作∃S extends T:G< S >

Angela关于从“上到下”阅读类型的解释实际上意味着包含?的类型隐含的虚拟存在量词总是尽可能靠近?。例如,您应该在心中将G< H< ? extends T > >重写为G<S extends T:H< S > >。由于外部没有量词,因此称为具体。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接