【问题标题】:Error: Found 'T', required: '? extends Liquid' [duplicate]错误:找到“T”,需要:“?扩展液体'[重复]
【发布时间】:2018-03-10 12:49:20
【问题描述】:

我在尝试使用基本泛型时遇到了一些错误。以下是挑战的简化版本;

public final class Example {
    private List<? extends Liquid> holder;
    private List<List<? extends Liquid>> holder2;

    public Example() {
        holder = new ArrayList<>();
        holder2 = new ArrayList<>();
    }

    public <T extends Liquid> void add(int position, T value) {
        if (holder != null)
            holder.add(position, value); //<- Error Here
    }

    public <T extends Liquid> void add(int position, List<T> value) {
        if (holder != null)
            holder.add(position, value); //<- This works
    }
}

客户

我希望变量持有者存储不同的液体subtypes。例子;

exampleInstance.add(0, new Water()); 
exampleInstance.add(1, new Juice());

【问题讨论】:

  • 这里的关键见解是List&lt;? extends Liquid&gt; 确实不是 表示“Liquid 的各种子类的列表”。它的意思是“各种对象的列表,它们都是Liquid相同 子类型,但我不知道具体是哪一个”。如果您理解这一点,那么这里的其余行为应该是有意义的。

标签: java generics


【解决方案1】:

使用上限通配符声明您的字段:List&lt;? extends Liquid&gt; holder 仅当您将分配给它的子类或想要在方法中传递它时才有意义。
在这种情况下,您不能在 List 中添加任何内容,只能添加 null。

您不在它的用例中。 因此,请声明 private List&lt;Liquid&gt; holder 以便能够在您的列表中添加 Liquid 实例。

【讨论】:

  • 我希望变量 holder 具有不同的 Liquid 子类型。例子; exampleInstance.add(0, new Water()); exampleInstance.add(0, new Juice());
  • 它会添加到List&lt;Liquid&gt; 任何Liquid 实例中(因此是Liquid 或子类)
  • 我正在尝试一下。
  • 令人困惑的是,在同一个类中,有另一个局部变量,如private List&lt;List&lt;? extends Liquid&gt;&gt; holder2;,它与通配符一起工作。使用其他局部变量(没有您的解决方案)private List&lt;? extends Liquid&gt; holderForSingle; 不起作用。为什么它的行为不同?为您的解决方案 +1。
  • 因为同级没有指定上界通配符。所以你没有同样的限制。您不能在 List&lt;? extends Foo&gt; 中添加任何 null 元素,但可以在 List&lt;List? extends Foo&gt;&gt; 中添加
猜你喜欢
  • 2020-06-01
  • 2017-12-07
  • 2019-07-01
  • 2017-01-20
  • 2014-01-29
  • 2019-01-19
  • 2017-04-09
  • 1970-01-01
  • 2016-01-23
相关资源
最近更新 更多