-5

The whole idea of Generics is type-safety and preventing casts.

When i add() to a list that is <? super A>, the only way it lets me compile the get is to declare the variable type as Object.

    ArrayList<? super A> list = new ArrayList<A>();

    Object obj = list.get(0);

The fact is that I can only add A and A's sub-classes to this list.

So one, why doesnt it let me declare obj as type A?

A obj = list.get(0);

And two, the fact that type is now Object, it seems to loosen up the whole Generics idea - i am containing it in a umbrella type, and i need to cast the .get()

bcsb1001
  • 2,606
  • 3
  • 22
  • 33
jforex78
  • 195
  • 1
  • 9

2 Answers2

2

You define the list as a list of <? super A>, this means the list contains elements which are A, or any of it's superclasses, this causes a problem, because there can be any number of superclasses, which could go all the way up to object, so all the compiler can guarantee is that the item returned from the list is an object.

If you want to have a list that contains As you should define it as a List<A> which guarentees the list will contain only As or A's subclasses

jrtapsell
  • 5,698
  • 1
  • 21
  • 46
  • Hi, actually, i am unable to add a superclass of A to this list. I cannot add a new Object() to it, for example. It gives me a capture #1 error. I can only add A and its subclasses to this list. So, i should be able to decalre the variable type from get as A, because it can only be of type A. – jforex78 Aug 27 '17 at 00:03
  • A much more in depth explanation is available here: https://stackoverflow.com/a/4343547/8041461 – jrtapsell Aug 27 '17 at 00:06
  • Hmm. It seems that using only thing i can .add() to `list` is A's subclasses, but `list` itself can point to A's superclasses. If not strange, its an Interesting finding. – jforex78 Aug 27 '17 at 00:17
  • 1
    @jforex78 Just because *you* cannot add `A`s to the list doesn't mean it only contains `Object`s. The *entire point* of wildcards is that the caller of code that uses it gets more freedom at the expense of the implementer's freedom (or the other way, in some cases). See: `void f(List super String> l) { l.add("Hello!"); } List l = new ArrayList<>(); l.add(new Object()); f(l);` – HTNW Aug 27 '17 at 00:38
  • Sorry, typo. Should be "Just because you can only add subtypes of `A` to the list doesn't mean it only contains `A`s." – HTNW Aug 27 '17 at 00:58
1

If you have a variable of type List<? super A>, you can only add values of type A to it through that variable. That doesn't mean it can't have other objects in it:

List<Object> l = new ArrayList<>();
l.add(new Object());
List<? super A> l2 = l;

l2.add can only be called with values of type A, but l2.get could return non-A instances.

user2357112 supports Monica
  • 215,440
  • 22
  • 321
  • 400