上界通配符在 Java 中导致编译错误
Upper bounded wildcards causing compilation error in Java
我不明白为什么会出现这些编译错误:
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
}
您可以像这样实例化 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());
}
}
对于 List<? extends Bird>
,您实际上说的是 任何类型,它是 Bird 的子类型,或者更准确地说,未知,但特定类型是 Bird
的子类型。这与说 扩展 Bird
.
的每种类型不同
也就是说?
可以是Sparrow
,也可以是Blackbird
。如果您尝试将 Sparrow
添加到 可能 仅包含 Blackbird
的列表中,它将不起作用。出于同样的原因,您不能将 Bird
添加到列表中,而 可能 是 Sparrow
的列表。
为了使事情正常进行,您只需将列表的声明更改为:
List<Bird> birds = new ArrayList<>();
或使用下限:
List<? super Bird> birds = new ArrayList<>();
关于这个下限示例:声明实际上说 任何类型 Bird
或其超类之一 .这意味着您可以安全地添加 Sparrow
或 Bird
,因为它们都满足这些条件。
一般来说,写入列表时应使用? super ...
,读取列表时应使用? extends ...
。如果您既要阅读又要写作,则不应使用边界。
This answer 提供了关于泛型的非常有用的信息。你绝对应该读一读。
我不明白为什么会出现这些编译错误:
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
}
您可以像这样实例化 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());
}
}
对于 List<? extends Bird>
,您实际上说的是 任何类型,它是 Bird 的子类型,或者更准确地说,未知,但特定类型是 Bird
的子类型。这与说 扩展 Bird
.
也就是说?
可以是Sparrow
,也可以是Blackbird
。如果您尝试将 Sparrow
添加到 可能 仅包含 Blackbird
的列表中,它将不起作用。出于同样的原因,您不能将 Bird
添加到列表中,而 可能 是 Sparrow
的列表。
为了使事情正常进行,您只需将列表的声明更改为:
List<Bird> birds = new ArrayList<>();
或使用下限:
List<? super Bird> birds = new ArrayList<>();
关于这个下限示例:声明实际上说 任何类型 Bird
或其超类之一 .这意味着您可以安全地添加 Sparrow
或 Bird
,因为它们都满足这些条件。
一般来说,写入列表时应使用? super ...
,读取列表时应使用? extends ...
。如果您既要阅读又要写作,则不应使用边界。
This answer 提供了关于泛型的非常有用的信息。你绝对应该读一读。