Java Generics,返回泛型扩展

时间:2011-01-11 11:31:37

标签: java generics

为什么我不允许这样做?

public abstract class A {}
public class B extends A {}
...

public ArrayList<A> foo()
{
  return new ArrayList<B>();
}

我改为公开,因为有很多人喜欢指出愚蠢的错误。

为什么我要编写所有这些代码。只是为了满足Java的无意义?

public List<A> foo() 
{ 
  List<A> aList = new ArrayList<A>(); 
  List<B> bList = new ArrayList<B>();
  /* fill bList*/

  for (B b : bList)
  {
    aList.add(b);
  }
  return aList;
}

3 个答案:

答案 0 :(得分:13)

ArrayList<B>不是ArrayList<A>。例如,您无法向其中添加任意A。或者我喜欢这样想:一堆香蕉不是水果碗。当你尝试将苹果添加到一堆香蕉中时,它会滚落......

您可以使用通配符使其工作:

public ArrayList<? extends A> foo()
{
    return new ArrayList<B>();
}

有关详细信息,请参阅Java Generics FAQ

编辑:要回答您为什么需要编写所有额外代码的具体问题:您没有。只需在ArrayList<A>内创建一个foo()即可。无需将一个列表的内容复制到另一个列表中。

如果您仍然反对Java的行为,那么您希望想要以下代码发生什么?

// Doesn't compile, fortunately...
List<String> strings = new List<String>();
List<Object> objects = strings;
objects.add(new Date());
String string = strings.get(0); // Um, it's a Date, not a String...

答案 1 :(得分:3)

a)首先,Java中不存在function。 Java方法的格式为

modifiers <type_parameters[,type_parameter]*>? return_type method_name (
   [parameter[,parameter]*]?
) [throws exceptiontype[, exceptiontype]*]{ method_body }

b)以下是如何操作:

public List<? extends A> foo()
{
  return new ArrayList<B>();
}

c)我将方法签名更改为List。如果存在适当的接口,那么在类的外部API中使用实现类型是不好的做法。

答案 2 :(得分:2)

因为ArrayList<B>()不是ArrayList<A>。它没有从它扩展

B extends A 表示ArrayList<B>() extends ArrayList<A>()