Question

public class POJO<T> {

    private List<Integer> integer = new ArrayList<Integer>();

    public POJO() {
        integer.add(1);
        integer.add(2);
    }

    public List<Integer> getInteger() {
        return integer;
    }

    public static void main(String[] args) {
        POJO pojo = new POJO();
        List<String> integer = pojo.getInteger(); // No compile error?
        System.out.println(integer); // prints [1, 2]
    }
}

How is it possible for the following line to compile:

List<String> integer = pojo.getInteger();

Provided getInteger() is typed as following

public List<Integer> getInteger()
Was it helpful?

Solution

I found a reference in the JLS 4.8 that backs up what @PeterLawrey says:

The type of a constructor (§8.8), instance method (§8.4, §9.4), or non-static field (§8.3) M of a raw type C that is not inherited from its superclasses or superinterfaces is the raw type that corresponds to the erasure of its type in the generic declaration corresponding to C.

So all instance methods of your raw POJO object are erased, including those that don't reference the type T of POJO<T>, which means (JLS 4.6):

The type parameters of a [...] method (§8.4.4), and the return type (§8.4.5) of a method, also undergo erasure if the [...] method's signature is erased.

OTHER TIPS

As pojo is not declared as a generic

POJO pojo = new POJO();

the compiler assumes you are using it in pre-generic code. i.e. where generics were added after the code was written. So when you do

List<String> integer = pojo.getInteger(); 

You get a warning rather than an error.

i.e. If the type is non-generic, all generic checks are turn off, not just those which relate to the type you didn't give it. I believe this is for maximum backward compatibility.

For comparison.

Map mapOfInteger = new Map(); // no generics
Set<String> entries = map.entrySet(); // gives a warning, not an error.

In this example, You might expect Set<Entry<K, V>> to become Set<Entry> if not generic, but the compiler falls back to treating the class a non-generic Set.

This is an unchecked assignment that is not treated as error for compatibility reasons.

See Interoperating with Legacy Code

In reality, the assignment is legal, but it generates an unchecked warning.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top