如何使用通配符实例化泛型? [英] How to instantiate generics using wild card?
问题描述
让我们使用通配符研究一些通用实例化情况:
Lets research some generic instantion situation using wild card:
此代码
List<?> list = new ArrayList<?>();
产生以下错误:
required: class or interface without bounds
found: ?
2
但是这个
2
But this
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>>>
5
List<Set<?>> list = new ArrayList< HashSet<?> >();
生成
required: List<Set<?>>
found: ArrayList<HashSet<?>>
我对这些输出感到非常困惑.
I am very confusing about these outputs.
我看到以下规律:
我只能在第一级上从左侧部分的左侧部分替换?
,并且类型在<>内应该相同并且只是?和 ?是禁止的.
I can replace ?
from left part on right part only on first level and types should be same inside <> and just ? and ? is forbid.
但是我不明白为什么?
But I don't understand why?
您能否提供通用规则,说明如何使用通配符实例化泛型?
Can you provide common rules how to instantiate generics using wild card?
推荐答案
- 您不能使用通配符直接实例化类型.实例化时,type参数必须是实际类型,因此会产生编译器错误.
代码:
List<?> list = new ArrayList<?>();
- 以下成功编译.
代码:
List<?> list = new ArrayList< Set<?> >();
您可以使用通配符作为类型参数的泛型类型参数,例如Set<?>
,它是任何东西的集合.另外,任何类型的参数都将匹配左侧的通配符?
.
You can use a wildcard as a generic type parameter to a type argument, e.g Set<?>
, a set of anything. Also, any type argument will match the wildcard ?
on the left.
- 这也可以成功编译:
代码:
List<Set<?>> list = new ArrayList< Set<?> >();
类型参数匹配,并且?
不像上面的(1)中那样直接使用.
The type arguments match, and ?
isn't used directly as in (1) above.
- 以下内容无法编译:
代码:
List<Set<Map<?,?>>> list = new ArrayList< Set<Map<String,String>> >();
这是因为即使Map<String, String>
是Map<?, ?>
,List<Set<Map<String, String>>>
也不是List<Set<Map<?, ?>>>
. Java泛型是不变的,这意味着类型参数必须匹配; "is-a"关系必须使用上限明确指定通配符.例如.通过在左侧引入上限通配符来编译此更改.
This is because even though a Map<String, String>
is a Map<?, ?>
, a List<Set<Map<String, String>>>
is not a List<Set<Map<?, ?>>>
. Java generics are invariant, meaning that type parameters must match; the "is-a" relationship must be specified explicitly with wildcards in upper bounds. E.g. this change compiles, by introducing upper bound wildcards on the left side.
List<? extends Set<? extends Map<?,?>>> list = new ArrayList< Set<Map<String,String>> >();
- 以下代码由于与上述(4)中相同的原因而无法编译:
代码:
List<Set<?>> list = new ArrayList< HashSet<?> >();
即使HashSet<?>
是Set<?>
,由于Java不变的泛型,ArrayList<HashSet<?>>
也不是List<Set<?>>
.在左侧引入通配符作为上限也可以在这里使用:
Even if a HashSet<?>
is a Set<?>
, because of Java's invariant generics, an ArrayList<HashSet<?>>
is not a List<Set<?>>
. Introducing wildcards on the left as upper bounds works here too:
List<? extends Set<?>> list = new ArrayList< HashSet<?> >();
这篇关于如何使用通配符实例化泛型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!