steve steve - 5 months ago 27
Java Question

difficulty understanding wildcards

public static void reverse(List<?> list)
{
List<Object> tmp = new ArrayList<Object>(list);
for (int i = 0; i < list.size(); i++)
{

list.set(i, tmp.get(list.size()-i-1)); // compile-time error , why ?

}

}


I am learning generics .
I know this : When a wildcard is used the ? gets replaced with the appropriate type . When reverse() method is called the ? will get replaced and since every type is a subtype of Object , there should be no error .
I am looking for a crystal clear explanation . Please help .

Answer Source

You can pass any List<SomeType> to your reverse method as the List<?> list argument, and the compiler should only allow you to add elements of SomeType to that List.

For example, it could be a List<String>, a List<Ineger>, etc...

Therefore list.set cannot work, since the compiler doesn't know the element type that the actual List<?> list passed to the method supports. It doesn't know that the elements of List<Object> tmp originated from the same list (and therefore can be added to it safely).

The correct way to write your method is to define a generic type parameter:

public static <T> void reverse(List<T> list) 
{ 
    List<T> tmp = new ArrayList<> (list);
    for (int i = 0; i < list.size(); i++)  {
        list.set(i, tmp.get(list.size()-i-1));
    }
}

Now the compiler knows that list and tmp both contain elements of the same type.