带有下限通配符的编译错误

时间:2018-04-19 17:19:29

标签: java generics java-8

考虑以下示例:

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 )。

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

2 个答案:

答案 0 :(得分:1)

当你说

  

下限通配符接受通配符

中给定类的超类的所有类

它指的是参数化类型,而不是可以传递给方法的对象类型。您可以为该变量分配List<Exception>,甚至是List<Object>

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

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

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

当然,人们可以完全放弃约束:

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

答案 1 :(得分:0)

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

library(tidyverse)

(foo <- data_frame(x = letters[1:3], y = LETTERS[4:6], z=1:3))
#> # A tibble: 3 x 3
#>   x     y         z
#>   <chr> <chr> <int>
#> 1 a     D         1
#> 2 b     E         2
#> 3 c     F         3

foo %>% 
  mutate_at(vars(x, y), factor)
#> # A tibble: 3 x 3
#>   x     y         z
#>   <fct> <fct> <int>
#> 1 a     D         1
#> 2 b     E         2
#> 3 c     F         3

然后,应该禁止使用List<? super IOException> exceptions = new ArrayList<IOException>(); ,因为exceptions.add(new Exception())无法容纳ArrayList<IOException>

解决方案是使用:

Exception

甚至:

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