0

It is made in java, that generics are not automatically converted from Generic<A> to Generic<SupeclassOfA>.

For example, if write a method

public static void printList(List<Object> list) {
    for (Object elem : list)
        System.out.println(elem + " ");
    System.out.println();
}

it will not accept List<Integer>. I need to rewrite header for List<?> and it will start work although the code will be the same.

So, why is it done?

Suppose I redesign Java so that List<?> always mean the same as List<Object>. What problems will I face?

Suzan Cioc
  • 29,281
  • 63
  • 213
  • 385

2 Answers2

1

Suppose a method taking a List<Object> accepted a List<Integer>. That would mean List<Integer> was a subtype of List<Object>. If that were true you could do this:

List<Integer> intList = new ArrayList<Integer>();
List<Object> objList = (List<Object>) intList;
objList.add("foo");
int a = intList.get(0);  // This would fail at runtime because intList.get(0) is a String.

So if you could cast a List<Integer> to a List<Object> you would lose the compile-time type safe safety that generics provide.

List<?> is not the same as List<Object>. List<?> is a List of some unknown type T. Since T is unknown it is not possible to add anything to a List<?> (except null). This is in complete contrast to a List<Object> where you can add anything.

As a general rule, List<Object> is very rarely what you need. Most of the time you want a List where all the items have the same type, like a List<Integer> or a List<String>. If you are writing a method where the type is not important, such as your example that just prints the items, the argument should have type List<?>.

Paul Boddington
  • 37,127
  • 10
  • 65
  • 116
0

You also are able to declare a upper bound. So you say :

List<? extends Foo> list

this will cause that you only are able to to things in the list which are subclasses of foo. in you case write extends Object. So Integer is a subclass an can be inserted.

ansanders
  • 7
  • 1
  • 9