1

In another SO post, the following example is given as a response to an OP:

public static <E> void funct1(final List<E> list1, final E something)
{
    list1.add(something);
}

public static void funct2(final List<?> list, final Object something)
{
    list.add(something); // does not compile
}

I have verified that funct1 compiles whereas funct2 does not. However, I am unable to figure out why.

Community
  • 1
  • 1
Schemer
  • 1,635
  • 4
  • 19
  • 39

2 Answers2

8

A List<?> is a list of a specific yet unknown type. The compiler can't allow a call on a method with the generic type parameter, because type safety can't be guaranteed. It could be a List<Integer>, or a List<Foo>, and one shouldn't be able to add an Object to it. The compiler must prevent this call with a compiler error to preserve the type safety that generics provides.

The method funct1 compiles because you can always add an E to a List<E>; it's the same type reference: E.

rgettman
  • 176,041
  • 30
  • 275
  • 357
  • What rules out type inference in this case? – Schemer Feb 27 '14 at 23:12
  • 1
    There is no type to infer in the `List>` case. The `?` wildcard doesn't infer the type from the object being added to the `List`. The `?` wildcard means that we deliberately don't know or care about the actual type, as long as it is one specific type. – rgettman Feb 27 '14 at 23:28
4

rgettman is right, but it's important to state that this doesn't only apply to List. It applies to all generic types.

If you declare a variable of a parameterized type with a wildcard ?, you cannot use the corresponding type variable which the parameterized type declares for anything because you don't know what its value is. However, you can use null with it, since null can be used anywhere a value of some reference type is expected.

For example

public class Example {
    public static void main(String[] str) throws Exception {
        Parameterized<?> exp = new Parameterized<String>();
        // below won't compile
        /*
           exp.something("tried my best");
           exp.something(666);
        */


        // below will compile
        exp.something(null);
    }    
}
class Parameterized<T> {
    public void something(T value) {}
}
Community
  • 1
  • 1
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724