Upper bounded wildcards causing compilation error in Java

て烟熏妆下的殇ゞ 提交于 2020-03-23 12:09:09

问题


I cannot understand why I am getting these compilation errors:

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
}

回答1:


With List<? extends Bird> you actually say any type that is a subtype of Bird1. It's not the same as saying every type that extends Bird.

That means that ? can be a Sparrow, but it can also be a Blackbird. If you try to add a Sparrow to a list that could contain only Blackbirds, it won't work. For that same reason you cannot add a Bird to a list that could be a List of Sparrows.

In order to make things work, you just change the declaration of the list to this:

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

or use lower bound:

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

About this lower bound example: the declaration actually says any type that is a Bird or one of its superclasses. That means that you can safely add a Sparrow or a Bird, because both meet those criteria.

Generally speaking, you should use ? super ... when you are writing to the list, and ? extends ... when you are reading from the list. If you are both reading and writing, you shouldn't use bounds.


This answer provides very useful information about generics. You definitely should read it.


1 I think the following statement is even more accurate: "an unknown, but specific type that is a subtype of Bird".




回答2:


You can instantiate the birds list like this:

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

Full code:

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());
    }
}


来源:https://stackoverflow.com/questions/44516990/upper-bounded-wildcards-causing-compilation-error-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!