如何使用通配符实例化泛型?

gst*_*low 5 java generics wildcard instantiation

让我们使用通配符研究一些通用实例情况:

1

这段代码

List<?> list = new ArrayList<?>();
Run Code Online (Sandbox Code Playgroud)

生成以下错误:

required: class or interface without bounds
found:    ?
Run Code Online (Sandbox Code Playgroud)

2

但是这个

List<?> list = new ArrayList< Set<?> >();
Run Code Online (Sandbox Code Playgroud)

编译成功。

3

和这个:

List<Set<?>> list = new ArrayList< Set<?> >();
Run Code Online (Sandbox Code Playgroud)

也编译成功。

4

但是这个:

List<Set<Map<?,?>>> list = new ArrayList< Set<Map<String,String>> >();
Run Code Online (Sandbox Code Playgroud)

产生

required: List<Set<Map<?,?>>>
found:    ArrayList<Set<Map<String,String>>>
Run Code Online (Sandbox Code Playgroud)

5

List<Set<?>> list = new ArrayList< HashSet<?> >();
Run Code Online (Sandbox Code Playgroud)

产生

required: List<Set<?>>
found:    ArrayList<HashSet<?>>
Run Code Online (Sandbox Code Playgroud)

我对这些输出感到非常困惑。

我看到以下规律:

我只能在第一级从左侧部分替换?右侧部分,并且 <> 内的类型应该相同,只是 ? 和 ?是禁止的。

但我不明白为什么?

您能否提供如何使用通配符实例化泛型的通用规则?

rge*_*man 3

  1. 您不能使用通配符直​​接实例化类型。实例化时,类型参数需要是实际类型,因此这会生成编译器错误。

代码:

List<?> list = new ArrayList<?>();
Run Code Online (Sandbox Code Playgroud)
  1. 出现以下内容则编译成功。

代码:

List<?> list = new ArrayList< Set<?> >();
Run Code Online (Sandbox Code Playgroud)

您可以使用通配符作为类型参数的泛型类型参数,例如Set<?>,一组任何内容。?此外,任何类型参数都将匹配左侧的通配符。

  1. 这也成功编译:

代码:

List<Set<?>> list = new ArrayList< Set<?> >();
Run Code Online (Sandbox Code Playgroud)

类型参数匹配,并且?不像上面的 (1) 那样直接使用。

  1. 以下内容无法编译:

代码:

List<Set<Map<?,?>>> list = new ArrayList< Set<Map<String,String>> >();
Run Code Online (Sandbox Code Playgroud)

这是因为即使 aMap<String, String>是 a Map<?, ?>,aList<Set<Map<String, String>>>也不是 a List<Set<Map<?, ?>>>。Java 泛型是不变的,这意味着类型参数必须匹配;“is-a”关系必须在上限中使用通配符明确指定。例如,此更改通过在左侧引入上限通配符进行编译。

List<? extends Set<? extends Map<?,?>>> list = new ArrayList< Set<Map<String,String>> >();
Run Code Online (Sandbox Code Playgroud)
  1. 由于与上面 (4) 中相同的原因,以下内容无法编译:

代码:

List<Set<?>> list = new ArrayList< HashSet<?> >();
Run Code Online (Sandbox Code Playgroud)

即使 aHashSet<?>是 a Set<?>,由于 Java 的不变泛型, anArrayList<HashSet<?>>也不是 a List<Set<?>>。在左侧引入通配符作为上限也适用于此:

List<? extends Set<?>> list = new ArrayList< HashSet<?> >();
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

2303 次

最近记录:

6 年,3 月 前