为什么我用这个Java代码会出现编译器错误?
1 public List<? extends Foo> getFoos()
2 {
3 List<? extends Foo> foos = new ArrayList<? extends Foo>();
4 foos.add(new SubFoo());
5 return foos;
6 }Run Code Online (Sandbox Code Playgroud)
其中'SubFoo'是实现Foo的具体类,而Foo是一个接口.
我用这段代码得到的错误:
更新:感谢Jeff C,我可以更改第3行来说"new ArrayList <Foo>();".但我仍然遇到第4行的问题.
eri*_*son 29
请改用:
1 public List<? extends Foo> getFoos()
2 {
3 List<Foo> foos = new ArrayList<Foo>(); /* Or List<SubFoo> */
4 foos.add(new SubFoo());
5 return foos;
6 }
Run Code Online (Sandbox Code Playgroud)
一旦声明foos List<? extends Foo>,编译器就不知道添加SubFoo是安全的.怎么ArrayList<AltFoo>分配给foos怎么办?这将是一个有效的赋值,但添加SubFoo会污染集合.
Gle*_*est 15
我只是想通过总结用类型或通配符实例化的List参数的属性来添加这个旧线程....
当方法的参数/结果是List时,使用类型实例化或通配符确定
List< Foo>List< Foo>List< Foo>List< ? super Foo>List< ? super SubFoo>List< ? extends Foo>List< ? extends SuperFoo>Foo 和亚型Foo和超类型(最多Object)List< ? extends Foo>List< Foo>List< Subfoo>List< SubSubFoo>List< ? extends Foo>List< ? extends SubFoo>List< ? extends SubSubFoo>List< ? extends Foo>List< ? extends SuperFoo>List< ? extends SuperSuperFoo>Foo和超类型(最多Object)List<? super Foo>List< Foo>List< Superfoo>List< SuperSuperFoo>List< ? super Foo>List< ? super SuperFoo>List< ? super SuperSuperFoo>List< ? super Foo>List< ? super SubFoo>List< ? super SubSubFoo>Foo 和超类型Foo和超类型(最多Object)List<Foo>如果呼叫者代码始终专注于操纵Foo类,因为它的读取和写入最大的灵活性List<? extends UpperMostFoo>是否可能有许多不同类型的来电显示,集中操作不同的类(并不总是富),并有在Foo类型不同层次的单一最上层阶级,如果该方法是在内部写列表和来电列表操作在看书.List< UpperMostFoo>在返回之前,该方法可以在内部使用并向其添加元素List< ? extends UpperMostFoo> List< ? super LowerMostFoo>小智 7
尝试:
public List<Foo> getFoos() {
List<Foo> foos = new ArrayList<Foo>();
foos.add(new SubFoo());
return foos;
}
Run Code Online (Sandbox Code Playgroud)
通用的ArrayList构造函数需要具有要参数化的特定类型,不能使用'?' 那里有通配符.将实例化更改为"new ArrayList <Foo>()"将解决第一个编译错误.
'foos'变量的声明可以有通配符,但由于你知道精确的类型,因此在那里引用相同的类型信息更有意义.你现在所说的foos拥有一些特定的Foo子类型,但我们不知道哪个.可能不允许添加SubFoo,因为SubFoo不是"Foo的所有子类型".将声明更改为'List <Foo> foos ='可以解决第二个编译错误.
最后,我将返回类型更改为"List <Foo>",因为此方法的客户端将无法对当前定义的返回值执行太多操作.您应该很少在返回类型中使用通配符.如果需要,使用参数化方法签名,但更喜欢有界类型仅出现在方法参数中,因为这会将其留给可以传递特定类型并相应地操作的调用者.