Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Generics: Type erasure of other fields in generic class [duplicate]

Tags:

java

generics

I have found a strange behavior when working with generics.

In this class Foo<T>, the strings member doesn't have anything to do with T:

package test;
import java.util.ArrayList;

public class Foo<T> {
    ArrayList<String> strings;

    T getSome() {
        return null;
    }
}

The class is used in main:

package test;

public class Main {

    public static void main() {
        Foo<Integer> intFoo = new Foo<>();
        Integer i = intFoo.getSome();
        String s1 = intFoo.strings.get(0);

        Foo rawFoo = new Foo();
        Object o = rawFoo.getSome();
        String s2 = rawFoo.strings.get(0); // Compilation error on this line
    }
}

The compilation error is "incompatible types. required: String found: Object".

It appears that Java forgets the String type argument to ArrayList when raw type of Foo is used.

My java version is 1.7.0_21

like image 456
Niklas Avatar asked Oct 08 '13 13:10

Niklas


1 Answers

Simply put, because rawFoo is raw, its non-static members also become raw.

This is outlined in JLS §4.8:

More precisely, a raw type is defined to be one of:

  • The reference type that is formed by taking the name of a generic type declaration without an accompanying type argument list.

  • An array type whose element type is a raw type.

  • A non-static member type of a raw type R that is not inherited from a superclass or superinterface of R.

Note the last bullet.

like image 159
arshajii Avatar answered Oct 14 '22 08:10

arshajii