开发者

Using generic collections in arguments

Let's say you have:

public interface A {}

public class B implements A {}

public class C {
  void foo (List<A>) {}
}

public class Test {
  //Declaration one
  List<A> x = new List<A>();

  //Declaration two
  List<A> x = new List<B>();

  B b = new B();
  x.add(b);


  new C().foo(x);
}

Now obviously declaration one is the correct way to do this, and you receive a compile error on declaration two. I would like to know though why Java chooses to enforce type safety in this specific manner; if a list o开发者_如何转开发f Cats is still a list of Animals, why does a method expecting a list of animals balk at receiving a bunch of cats?

Curiousity, more than anything else - and a chance to better refine my knowledge.

Cheers, Dave.


Java generics are not covariant. If you could do this:

ArrayList<Animal> x = new ArrayList<Cat>();

then you would be able to do:

x.add(new Dog());

which violates the concept that an ArrayList<Cat> can only hold Cat objects (or subclass objects).

Read this for for more details: Java theory and practice: Generics gotchas.


Why does a method expecting a list of animals balk at receiving a bunch of cats?

Because you can add any animal to that list, not just cats. This could result in a list of cats containing a dog, like so:

Using generic collections in arguments

The caller still thinks it's a list of cats and a dog dies when the caller tries to make them fall on his feet when dropped.


Use "extends" instead of the class directly :

List<? extends A>x;

If you use only the class as generic then all the elements mus be only of this class.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜