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

标签 java bounded-wildcard

我不明白为什么会出现这些编译错误:

1:

The method add(capture#1-of ? extends Exec.Bird) in the type List is not applicable for the arguments (Exec.Sparrow)

2:

The method add(capture#2-of ? extends Exec.Bird) in the type List is not applicable for the arguments (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
}

最佳答案

List<? extends Bird>您实际上说任何 Bird 子类型,或者更准确地说,未知但特定的类型,它是 Bird 的子类型。这与说扩展 Bird 的每种类型不同。

这意味着?可以是Sparrow ,但也可以是 Blackbird 。如果您尝试添加 Sparrow可能仅包含 Blackbird 的列表s,这是行不通的。出于同样的原因,您不能添加 Bird到一个列表,可能Sparrow 的列表s。

为了使事情正常工作,您只需将列表的声明更改为:

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

或使用下限:

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

关于这个下限示例:声明实际上表示任何类型 Bird或其父类(super class)之一。这意味着您可以安全地添加 SparrowBird ,因为两者都满足这些标准。

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

<小时/>

This answer提供有关泛型的非常有用的信息。您绝对应该阅读它。

关于java - Java 中导致编译错误的上限通配符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44516990/

相关文章:

java - 在普通 Java 应用程序中使用 JavaFX MediaPlayer 播放音频?

java.sql.Timestamp 到 Joda Instant,反之亦然

java - 如何用Jsoup爬取离线网页?

Java 泛型 : incompatible wildcard capture

java - Java 中的下限是排他性的还是包容性的?

Java 通配符读写权限

Java 泛型(有界通配符)

java - 需要帮助解释涉及泛型的 Java 代码

java - 并行数组 : how to initialize the length of the arrays when the input file is unknown