0

I can't see why size(test); won't compile. Can someone help me understand?

public class TestContainer<T extends Object> {
}

.

public class Main {
    public static int size(List<TestContainer<?>> list) {
        return list.size(); 
    }

    public static void main(String[] args) {
        List<TestContainer<Object>> test = new ArrayList<TestContainer<Object>>();
        size(test); // this does not compile
        test.size(); // of course this works fine
    }
}
bob
  • 37
  • 3

2 Answers2

0

A method with as parameter a generic List can accept subclasses of the generic type only if the List parameter declaration is parameterized with an upper bounded wildcard.

You don't declare any upper bounded wildcard (<? extend T>) for List<TestContainer> here :

public static int size(List<TestContainer<?>> list) {
    return list.size(); 
}

So you can only pass this exact type as parameter :

List<TestContainer<?>>

To achieve you want, you should so write :

public static int size(List<? extends TestContainer<?>> list) {
    return list.size(); 
}

Note that the upper bounded wildcard is designed to ensure the type safety of the passed List.
As a consequence, inside the method, you could not add anything in but null.
But for your use case (returning the size of the list), it is not a problem.

davidxxx
  • 104,693
  • 13
  • 159
  • 179
0

List<TestContainer<Object>> is not a List<TestContainer<?>>.

A TestContainer<Integer> is a TestContainer<?>. Therefore, you can add a TC<Integer> to a List<TC<?>>. Similarly, you can add a TC<String> to a List<TC<?>>.

However, a TC<Integer> is not a TC<Object> (because generics are invariant in Java), so you mustn't be allowed to add a TC<Integer> to a List<TC<Object>>. As such, a List<TC<Object>> isn't a List<TC<?>>.

If you make it so that you are unable to add anything (except literal null) to the List - by making the method parameter List<? extends TC<?>> (or List<?>, if you are really uninterested in the elements) - it is safe, and thus allowed.

Andy Turner
  • 122,430
  • 10
  • 138
  • 216