Schemer
Schemer

Reputation: 1665

Java Generics: Explanation of Example on SO

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.

Upvotes: 1

Views: 64

Answers (2)

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 279950

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) {}
}

Upvotes: 4

rgettman
rgettman

Reputation: 178263

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.

Upvotes: 8

Related Questions