上限有限的通配符导致Java中的编译错误

时间:2017-06-13 09:06:51

标签: java bounded-wildcard

我无法理解为什么我会收到这些编译错误:

1:

  

类型List中的方法add(capture#1-of?extends Exec.Bird)不适用于参数(Exec.Sparrow)

2:

  

类型List中的方法add(capture#2-of?extends Exec.Bird)不适用于参数(Exec.Bird)

static class Bird{}
static class Sparrow extends Bird{}

public static void main(String[] args){
    List<? extends Bird> birds = new ArrayList<Bird>();
    birds.add(new Sparrow()); //#1 DOES NOT COMPILE
    birds.add(new Bird());// //#2 DOES NOT COMPILE
}

2 个答案:

答案 0 :(得分:0)

您可以像这样实例化birds列表:

List<Bird> birds = new ArrayList<>();

完整代码:

import java.util.ArrayList;
import java.util.List;

public class Main {
    static class Bird{}
    static class Sparrow extends Bird{}

    public static void main(String[] args) {
        List<Bird> birds = new ArrayList<>();
        birds.add(new Sparrow());
        birds.add(new Bird());
    }
}

答案 1 :(得分:0)

使用List<? extends Bird>,您实际上会说 任何类型为Bird 的子类型。这与说出扩展Bird 的每种类型都不一样。

这意味着?可以是Sparrow,但它也可以是Blackbird。如果您尝试将Sparrow添加到 仅包含Blackbird的列表中,则无效。出于同样的原因,您无法将Bird添加到可能列为Sparrow列表的列表中。

为了使事情有效,您只需将列表声明更改为:

List<Bird> birds = new ArrayList<>();

或使用下限:

List<? super Bird> birds = new ArrayList<>();

关于此下限示例:声明实际上是 任何类型的Bird或其超类 。这意味着您可以安全地添加SparrowBird,因为两者都符合这些条件。

一般来说,在写入列表时应使用? super ...,在列表中阅读时应使用? extends ...。如果您同时阅读和写作,则不应使用边界。

This answer提供了有关泛型的非常有用的信息。你一定要读它。