为什么F <! - ?扩展栏 - >不分配给F <bar> </bar>

时间:2014-02-15 22:31:14

标签: java generics

这是SSCCE

import java.util.*;

class Test {
    public static void main(String[] args) {
        bar( foo() );
    }

    public static List<? extends CharSequence> foo() {
        return null;
    }

    public static void bar(List<CharSequence> baz) {
        // Nothing to see here
    }
}

这导致

bar(java.util.List<java.lang.CharSequence>) in Test cannot be applied to (java.util.List<capture#672 of ? extends java.lang.CharSequence>)
  1. 示例可能会失败吗?将<? extends CharSequence>投射到<CharSequence>是安全的,不是吗?
  2. 如果不是通过施法,我应该如何解决这个问题(在更复杂的设置中)?

2 个答案:

答案 0 :(得分:3)

让我们使用标准示例。你有课程

class Fruit{}
class Apple extends Fruit{}
class Banana extends Fruit{}

现在假设您已经参考了所有类型的水果列表,如

List<? extends Fruit> list;

此引用不仅可以保存Fruit列表,还可以保存AppleBanana列表。

List<? extends Fruit> list = new ArrayList<Apple>();
//lets say we add some apples here to list

您是否认为让List<Fruit>处理List<? extends Fruit>列表

是安全的
List<Fruit> fruits = list;

想一想。通过List<Fruit> ,您可以添加各种水果 到列表中。这意味着您可以将Banana添加到当前保留的Apples列表中。

这就是为什么Java不允许您使用foo() List<? extends CharSequence>的结果作为bar(List<CharSequence> baz)的参数。

答案 1 :(得分:2)

问题是,当foo()返回列表时,您不知道列表中包含的内容。

例如,假设foo()返回StringBuilder列表。但现在,bar()尝试向其添加String。你破坏了这份清单的类型安全性。

如果列表在bar()中没有变化,我建议更改栏以接受List<? extends CharSequence>,然后您就可以了。