如何使用通配符实例化泛型? [英] How to instantiate generics using wild card?

查看:76
本文介绍了如何使用通配符实例化泛型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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?

推荐答案

  1. 您不能使用通配符直​​接实例化类型.实例化时,type参数必须是实际类型,因此会产生编译器错误.

代码:

List<?> list = new ArrayList<?>();

  1. 以下成功编译.

代码:

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.

  1. 这也可以成功编译:

代码:

List<Set<?>> list = new ArrayList< Set<?> >();

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

The type arguments match, and ? isn't used directly as in (1) above.

  1. 以下内容无法编译:

代码:

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>> >();

  1. 以下代码由于与上述(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆