Generic Type Erase Prevention

I have this code from the book Thinking in Java where Bruce points out a warning about calling the set () method . The code looks like this:

    package testPackage;

    class GenericBase<T> {
    private T element;
    public void set(T arg) { arg = element; }
    public T get() { return element; }
    }
    class Derived1<T> extends GenericBase<T> {}
    class Derived2 extends GenericBase {} // No warning
    // class Derived3 extends GenericBase<?> {}
    // Strange error:
    // unexpected type found : ?
    // required: class or interface without bounds
    public class ErasureAndInheritance {
    @SuppressWarnings("unchecked")
    public static void main(String[] args) {
        Derived2 d2 = new Derived2();
        Object obj = d2.get();
        d2.set(obj); // Warning here!
        }
    }

      

If I remove the annotation, I get the following warning:
Security type. The set (Object) method is of the raw GenericBase type. GenericBase references should be parameterized

My question is, why is the warning displayed in the set () method ? And can someone please explain what this warning means?
By the way, I am completely new to Java Generics and although I have read other questions about Generics, I am still somewhat confused about Erasure .

+3


source to share


1 answer


From the Java doc here

Generics have been introduced to the Java language to provide more stringent compile-time type checks and supports universal programming. To implement generics, the Java compiler applies type erasure to:

  • Replace all type parameters in generic types with your bounds or object if type parameters are not constrained. The generated bytecode, therefore, contains only regular classes, interfaces, and methods.
  • Insert type as needed to maintain type safety.
  • Create bridging methods to preserve polymorphism on extended generic types.
  • Erasing styles ensures that no new classes are created for parameterized types; hence generics have no runtime overhead.

Simple: every pedigree Object

after the compilation process, it just adds casting for you and if you do something wrong it will lead to a compiler error.

About annotation unchecked

, it is used when the compiler cannot be sure that what you are doing is correct (in fact, you are using the raw type, which is the same as GenericBase<Object>

)



You have a warning with methods set

other than type T

, but since you are using a raw type it doesn't know what it T

is and generates this warning to let you know that you are using a raw type (bad thing).

You can use annotations to say, "I know it's a raw type, but I know it's legal and I know what I'm doing."

The mixing of raw and generic types is possible because of the way generics are implemented, as mentioned above, after the compiler process T

becomes Object

, which means that a raw object such as GenericBase

is the same as GenericBase<T>

.

The reason it doesn't ask for casting with generics is because it will add casts for you (and you can rest assured that the code will always run at runtime without worrying about the possible ClassCastException

).

+3


source







All Articles