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

标签 java generics wildcard instantiation

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

1

这段代码

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

生成以下错误:

required: class or interface without bounds
found:    ?

2

但是这个

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

编译成功

3

还有这个:

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

编译也成功

4

但是这个:

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<?>>

我对这些输出感到很困惑。

我看到以下规律:

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

但我不明白为什么?

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

最佳答案

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

代码:

List<?> list = new ArrayList<?>();
  1. 以下编译成功。

代码:

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

您可以使用通配符作为类型参数的泛型类型参数,例如 Set<?> ,一套任何东西。此外,任何类型参数都将匹配通配符 ?在左边。

  1. 这也编译成功:

代码:

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

类型参数匹配,?没有像上面 (1) 中那样直接使用。

  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”关系必须在上限中使用通配符明确指定。例如。此更改通过在左侧引入上界通配符来编译。

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<?>> .在左侧引入通配符作为上限也适用于此:

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

关于java - 如何使用通配符实例化泛型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26146371/

相关文章:

Java泛型 - 从方法返回声明类型的子类型

oracle10g - 通配符查询扩展导致术语过多

Python:导入 * 只从包中导入某些东西?

java - 源码包和测试包有什么区别?

c# - Xamarin Master Detail 句柄泛型

Java抽象方法签名

c# - C#泛型之间的类型转换有什么规则吗?

Linux 下载通配符 URL

java - 如何修复 Android Studio 依赖错误

java - 如何使用 spring boot 2 和千分尺测量服务方法