【问题标题】:Compilation error with lower-bounded wildcard带有下界通配符的编译错误
【发布时间】:2018-04-20 01:54:26
【问题描述】:

考虑以下示例:

public static void main(String... args) {
    List<? super IOException> exceptions = new ArrayList<Exception>();
    exceptions.add(new Exception());       // Compile Error
    exceptions.add(new IOException());
    exceptions.add(new FileNotFoundException());
}

我知道下界通配符接受通配符中给定类的超类的所有类(此处为 IOException)。

为什么在上述情况下编译器会显示编译错误?

【问题讨论】:

  • 如果是 ArrayList&lt;IOException&gt; 会怎样?

标签: java generics java-8


【解决方案1】:

当你说

下界通配符接受通配符中给定类的超类的所有类

指的是参数化类型,而不是可以传递给方法的对象的类型。您可以将List&lt;Exception&gt; 分配给该变量,甚至是List&lt;Object&gt;

编译器不能假定exceptions 可以容纳Exception。实际类型参数可能与下限一样具体,在本例中为IOException。将List&lt;IOException&gt; 分配给exceptions 是合法的,在这种情况下,您将无法添加Exception。因此,编译器不允许该语句。

如果您想添加 Exception 并保留下限,请将边界更改为:

List<? super Exception> exceptions = new ArrayList<Exception>();

当然可以完全放弃绑定:

List<Exception> exceptions = new ArrayList<>();

【讨论】:

  • 您提出的 List 声明方式与我在问题中提到的相同。我很害怕,我错过了什么吗?
  • 指的是类型参数... 我觉得参数化类型会更准确。也就是说,使用下限T 参数化的类型是使用超类型T 参数化的同一类型的超类型。
【解决方案2】:

您的代码无法编译的原因是以下内容是合法的:

List<? super IOException> exceptions = new ArrayList<IOException>();

那么,exceptions.add(new Exception()) 应该被禁止,因为ArrayList&lt;IOException&gt; 不能容纳Exception

一个解决方案是使用:

// No compiler errors
List<? super Exception> exceptions = new ArrayList<Exception>();
exceptions.add(new Exception());
exceptions.add(new IOException());
exceptions.add(new FileNotFoundException());

甚至:

// Also no compiler errors
List<Exception> exceptions = new ArrayList<>();
exceptions.add(new Exception());
exceptions.add(new IOException());
exceptions.add(new FileNotFoundException());

【讨论】:

  • 你是对的。 “IOException”不能容纳“Exception”。但是为什么“Exception”不能容纳“Exception”呢?
  • 编译器只关心列表声明的类型,在本例中为List&lt;? super IOException&gt;。这实际上可以引用List&lt;Exception&gt;List&lt;IOException&gt;,编译器在运行时不知道哪个是真的。所以编译器只允许在这两种情况下都可以的事情。无论哪种情况,添加IOException 都可以,但在后一种情况下添加Exception 是错误的。
猜你喜欢
  • 2023-03-06
  • 2020-12-13
  • 2012-08-08
  • 2017-11-06
  • 2013-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多