Java Basics: a deep understanding of generics


1. Java generics

2. How to implement Java generics?

Java generics are implemented throughType Erasure It’s true! That is, Java generics are pseudo generics. During compilation, all generics information will be erased. Therefore, the java compiler will find possible errors as much as possible at compile time, but it still can’t find the type conversion exception at run time.

Type erasure is also an important difference between Java generics and C + + template mechanism.Java Basics: a deep understanding of generics

2.1 proof of Java generic erasure

  • The type information is erased and the original type is the sameThe parameter types of the following two list containers are string and integer respectively. However, the type information of the two containers is erased during operation, and only the original type object is retained
    public class reflect {
      public static void main(String[] args){
          List<String> list1 = new ArrayList<>(); 
          List<Integer> list2 = new ArrayList<>();
          System.out.println(list1.getClass() == list2.getClass());//true
  • Add other types by reflectionIt can also prove that the generic type information is erased, leaving the original type!
    public class reflect {
      public static void main(String[] args) throws Exception{
          List<Integer> list1 = new ArrayList<>();

    Output results

    [13, a123]

2.2 original type after type erasure

  • Primitive typeThat is, the generic information is erased. Finally, the real type of the type variable in the bytecode is deleted. Whenever a generic type is defined, the corresponding original type will be provided automatically. The type variable is erased and theUse its qualified type (indefinite variables are replaced with object)Java Basics: a deep understanding of generics

    class info<T>{
      //Indefinitely, the original type is object
    class message<T extends Comparable>{
      //If there is a restriction, that is, comparable is the boundary, then use this restriction type
  • Therefore, when calling a generic class or method, you can specify a generic or not.Java Basics: a deep understanding of generics

    • Without specifying a generic type, the type of a generic variable is the minimum level of the same parent class of several types in the method, up to object
    • When a generic type is specified, several types of the method must be the type or subclass of the instance of the generic type

3. Problems caused by type erasure and Solutions

For various reasons, Java can’t implement real generics,Pseudo generics can only be implemented with type erasure, although there is no type inflation problemHowever, it also leads to many new problems, so sun has made various restrictions on these problems to avoid all kinds of mistakes

3.1 check before Compilation

Java Basics: a deep understanding of generics: since it is said that type variables will be erased during compilation, why do we report an error when we add integers to the objects created by ArrayList < integer >? Doesn’t it mean that the generic variable string will become object type at compile time? Why can’t we save other types? Now that the type is erased, how can we ensure that we can only use the type defined by generic variables?

ArrayList<String> list1 = new ArrayList(); 
list1.add("1"); //Compilation passed
list1.add(1); //Compilation error

Java Basics: a deep understanding of genericsJava compiler checks the type of generics in the code first, and then erases the type before compiling.

3.2 reference transfer

Discuss the situation:

ArrayList<String> list1 = new ArrayList(); //The first case
ArrayList list2 = new ArrayList<String>(); //The second situation

list1.add("1"); //Compilation passed
list1.add(1); //Compilation error
String str1 = list1.get(0); //The return type is string

list2.add("1"); //Compilation passed
list2.add(1); //Compilation passed
Object object = list2.get(0); //The return type is object

We can find that type checking depends on its reference, not on the type it points to. That is to say, the compiler will check with the qualified type if the reference is qualified. If not, the type of generic variable will be the minimum level of the same parent class of several types in the method until objectJava Basics: a deep understanding of genericsJava Basics: a deep understanding of genericsJava Basics: a deep understanding of generics

Let’s look at another situation

ArrayList<Object> list2 = new ArrayList<>(); 
list2.add(new Object());
ArrayList<String> list22 = list2;//Compilation error

The following is the personal understanding of the above code

First of all, if the List2 type has been defined as object, the added elements are all object. At this time, pointing it to the reference of ArrayList < string > is just like downward transformation, which is not allowed!

3.3 automatic type conversion

Because of the problem of type erasure, all generic type variables are eventually replaced with the original type. Since they are all replaced with the original type, why don’t we need to cast when we get them?

look downArrayList.get()method:

public E get(int index) {  


    return (E) elementData[index];  


As you can see, before return, strong conversion will be performed according to generic variables. Assuming that the generic type variable is date, although the generic information will be erased, the (E) elementdata [index] will be compiled as (date) elementdata [index]. So we don’t have to force ourselves.

This work adoptsCC agreementReprint must indicate the author and the link of this article

Recommended Today

Common business logic in PHP

How does PHP split and merge files when operating breakpoint continuation To realize breakpoint continuation in PHP, you need to divide a large file into multiple small files, and then upload them individually. Merge after transfer. │ merge.php – merge file script  \│ – merged file  \│ – files to be split  \│ […]