What is the concept of erasure in generics in Java?

前端 未结 8 700
误落风尘
误落风尘 2020-11-22 01:45

What is the concept of erasure in generics in Java?

8条回答
  •  梦谈多话
    2020-11-22 02:00

    Why use Generices

    In a nutshell, generics enable types (classes and interfaces) to be parameters when defining classes, interfaces and methods. Much like the more familiar formal parameters used in method declarations, type parameters provide a way for you to re-use the same code with different inputs. The difference is that the inputs to formal parameters are values, while the inputs to type parameters are types. ode that uses generics has many benefits over non-generic code:

    • Stronger type checks at compile time.
    • Elimination of casts.
    • Enabling programmers to implement generic algorithms.

    What is Type Erasure

    Generics were introduced to the Java language to provide tighter type checks at compile time and to support generic programming. To implement generics, the Java compiler applies type erasure to:

    • Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.
    • Insert type casts if necessary to preserve type safety.
    • Generate bridge methods to preserve polymorphism in extended generic types.

    [N.B.]-What is bridge method? To shortly, In the case of a parameterized interface such as Comparable, this may cause additional methods to be inserted by the compiler; these additional methods are called bridges.

    How Erasure Works

    The erasure of a type is defined as follows: drop all type parameters from parameterized types, and replace any type variable with the erasure of its bound, or with Object if it has no bound, or with the erasure of the leftmost bound if it has multiple bounds. Here are some examples:

    • The erasure of List, List, and List> is List.
    • The erasure of List[] is List[].
    • The erasure of List is itself, similarly for any raw type.
    • The erasure of int is itself, similarly for any primitive type.
    • The erasure of Integer is itself, similarly for any type without type parameters.
    • The erasure of T in the definition of asList is Object, because T has no bound.
    • The erasure of T in the definition of max is Comparable, because T has bound Comparable.
    • The erasure of T in the final definition of max is Object, because T has bound Object & Comparable and we take the erasure of the leftmost bound.

    Need to be careful when use generics

    In Java, two distinct methods cannot have the same signature. Since generics are implemented by erasure, it also follows that two distinct methods cannot have signatures with the same erasure. A class cannot overload two methods whose signatures have the same erasure, and a class cannot implement two interfaces that have the same erasure.

        class Overloaded2 {
            // compile-time error, cannot overload two methods with same erasure
            public static boolean allZero(List ints) {
                for (int i : ints) if (i != 0) return false;
                return true;
            }
            public static boolean allZero(List strings) {
                for (String s : strings) if (s.length() != 0) return false;
                return true;
            }
        }
    

    We intend this code to work as follows:

    assert allZero(Arrays.asList(0,0,0));
    assert allZero(Arrays.asList("","",""));
    

    However, in this case the erasures of the signatures of both methods are identical:

    boolean allZero(List)
    

    Therefore, a name clash is reported at compile time. It is not possible to give both methods the same name and try to distinguish between them by overloading, because after erasure it is impossible to distinguish one method call from the other.

    Hopefully, Reader will enjoy :)

提交回复
热议问题