开发者

Java Generics, return generic extending

Why am i not allowed to do this?

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

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

I chan开发者_运维问答ged to public since there are so many people that love to point stupid errors.

Why should i have to write ALL this code. Just to satisfy Java's non-senses?

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


An ArrayList<B> is not an ArrayList<A>. You can't add any arbitrary A into it, for example. Or as I like to think of it: a bunch of bananas isn't a fruitbowl. When you try to add an apple to a bunch of bananas, it rolls off...

You can use wildcards to make it work though:

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

See the Java Generics FAQ for more details.

EDIT: To answer your specific question of why you need to write all that extra code: you don't. Just create an ArrayList<A> within foo() to start with. There's no need to copy the contents of one list to another.

If you still object to Java's behaviour, what would you want to happen with the following code?

// 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...


a) For one thing, function does not exist in Java. Java methods have the format

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

b) Here's how to do it:

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

c) I changed the method signature to List. It's bad practice to have implementation types in your class' external API if an appropriate interface exists.


because ArrayList<B>() is not ArrayList<A>. it is not extended from it

B extends A doesn't mean ArrayList<B>() extends ArrayList<A>()

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜