让我们使用外卡研究一些通用的情况:
此代码
List<?> list = new ArrayList<?>();
生成以下错误:
required: class or interface without bounds
found: ?
但是这个
List<?> list = new ArrayList< Set<?> >();
编译成功。
和此:
List<Set<?>> list = new ArrayList< Set<?> >();
也是成功的。
但是这个:
List<Set<Map<?,?>>> list = new ArrayList< Set<Map<String,String>> >();
产生
required: List<Set<Map<?,?>>>
found: ArrayList<Set<Map<String,String>>>
List<Set<?>> list = new ArrayList< HashSet<?> >();
生成
required: List<Set<?>>
found: ArrayList<HashSet<?>>
我对这些输出感到非常困惑。
我看到以下规律:
我可以仅在第一级上从右侧部分的左侧部分替换?
,并且类型内部的类型应该相同&lt;&gt;只是?和?是禁止的。
但我不明白为什么?
您是否可以提供如何使用通配符实例化泛型的通用规则?
答案 0 :(得分:3)
代码:
List<?> list = new ArrayList<?>();
代码:
List<?> list = new ArrayList< Set<?> >();
您可以使用通配符作为类型参数的泛型类型参数,例如Set<?>
,一组任何东西。此外,任何类型参数都将匹配左侧的通配符?
。
代码:
List<Set<?>> list = new ArrayList< Set<?> >();
类型参数匹配,?
不能直接用于上面的(1)。
代码:
List<Set<Map<?,?>>> list = new ArrayList< Set<Map<String,String>> >();
这是因为即使Map<String, String>
是Map<?, ?>
,List<Set<Map<String, String>>>
也不是List<Set<Map<?, ?>>>
。 Java泛型是不变的,这意味着类型参数必须匹配; &#34;是-a&#34;必须使用上限中的通配符显式指定relationship。例如。通过在左侧引入上限通配符来编译此更改。
List<? extends Set<? extends Map<?,?>>> list = new ArrayList< Set<Map<String,String>> >();
代码:
List<Set<?>> list = new ArrayList< HashSet<?> >();
即使HashSet<?>
是Set<?>
,由于Java的不变泛型,ArrayList<HashSet<?>>
也不是List<Set<?>>
。在左边引入通配符作为上限也可以在这里工作:
List<? extends Set<?>> list = new ArrayList< HashSet<?> >();
答案 1 :(得分:2)
List<?>
一个类型Set<?>
。 Set<?>
是一种类型。ArrayList<T>
是List<T>
。<A extends B>
或<A super B>
内容)。 List<String>
不是List<Object>
的子类型。它是的子类型List<? extends Object>
或List<?>
。List<? extends Set<?>>
,那么它将起作用。