我正在阅读AngelikaLangerGenericsFaq的多级外卡。我很困惑 关于语法。该文件说
类型
Collection<Pair<String,?>>
是一个具体的实例 通用集合接口。它是一个异质的集合 对不同类型。它可以包含类型的元素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的哪个实例化 代表。根据经验,您必须自上而下阅读多级通配符。
我对以下几点感到困惑。
有人可以详细说明这些观点。感谢。
答案 0 :(得分:11)
有人可以通过示例详细说明这三个引号。我完全陷入了语法
嗯,在这里再次写下这三个引号是没有意义的。至于,我无法给出更好的解释。相反,我会尝试回答下面的其他问题,然后你也可能会理解这个问题。如果没有,您可以再次询问您的查询。我会稍微再详细说明一下。
文件说,para-1是泛型类型的具体实例,而其他不是具体的实例化?那怎么样?
具体实例化是所有类型参数都是具体类型的实例,并且在编译时是已知的。例如,List<String>
是一个具体的实例,因为String
是具体的类型。它的类型在编译时是已知的。鉴于List<? extends Number>
不是具体类型,因为? extends Number
可以是任何扩展Number
的类型。所以,它的类型在编译时是未知的。同样,Map<String, Integer>
是泛型Map<K, V>
的具体实例。
对于多级类型参数List<List<? extends Number>>
,外部List
是List<E>
的具体实例,因为已知元素类型为List
在编译时,尽管内部List
是通配符实例化,因为存储的元素类型可以是Integer
,Double
,Number
的任何子类。但该段只涉及外部类型。外部类型只能包含List
类型。
这就是为什么第一段说的,它是Pair
的异构集合,因为Pair
的实际类型参数可以是任何东西,但肯定是Pair
而没有别的
自上而下阅读外卡是什么意思?
用外行的话说,这意味着从左到右。在确定参数化类型的类型时,首先会看到最外面的类型参数。然后,如果该类型参数本身是参数化类型,则转到该参数化类型的类型参数。因此,我们从左到右阅读类型参数。
多级外卡有什么优势?
假设您要创建水果列表列表。现在你的内心List
可以包含任何种类的水果。 apple 也是 fruit , banana 也是 fruit 。所以,你必须确保你得到所有这些。现在,由于泛型类型是不变的,因此List<Apple>
与List<Fruit>
不同,如果您的列表类型为List<Apple>
,则无法添加List<List<Fruit>>
。为此,您需要使用wildcards
这样的List<List<? extends Fruit>>
,现在可以使用List<Apple>
,List<Banana>
,任何水果列表。
答案 1 :(得分:0)
带有通配符的通用类型实际上是“存在”类型。如果您对逻辑很熟悉,可以将G< ? extends T >
视为∃S extends T:G< S >
。
Angela关于阅读类型“自上而下”的解释实际上意味着包含?
的类型所暗示的虚构存在量词总是尽可能接近?
。例如,您应该在心理上将G< H< ? extends T > >
重写为G<
∃S extends T:H< S > >
。由于外部没有量词,因此称为具体。