Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 .

like image 601
cs-dev Avatar asked Jan 21 '26 03:01

cs-dev


1 Answers

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.

like image 199
Eran Avatar answered Jan 23 '26 17:01

Eran



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!