Generic Erase and transform
Teacher: Wang Shaohua QQ Group: 483773664 Learning Objectives:
Mastering the meaning of generic erase
Understanding rules for generic conversions
First, generic erase
(a) What generic erase
Generics in Java are basically implemented at the compiler level. In the generated Java bytecode, the type information in the generic is not included. That is, there is no generics in the virtual machine, only ordinary classes and common methods
When you use generics, the type parameter is removed when the compiler is compiled. This process is called type erasure.
The main process for type erasure is as follows:
1. Replace all generic parameters with their leftmost boundary (the top-most parent type) type.
2. Remove all the type parameters.
Types such as list<object> and list<string>, as defined in the code, will be programmed to list after compilation. The JVM sees only the list, and the type information appended by generics is not visible to the JVM.
123456789 |
public class Test { Public static void main (string[] args) { arraylist<string> arrayList1 = new ArrayList <String> (); Arraylist1.add ( "abc" ); arraylist<integer> arrayList2 = New arraylist<integer> (); Arraylist2.add ( 123 ); System.out.println (arraylist1.getclass () = = Arraylist2.getclass ()); } } |
In this example, we define two ArrayList arrays, but one is a arraylist<string> generic type and can only store strings. One is a arraylist<integer> generic type and can only store shaping. Finally, we get information about their class by ArrayList1 objects and the GetClass method of the ArrayList2 object, and we finally find the result to be true. Indicates that the generic type string and integer are erased, leaving only the original type.
(ii) Problems caused by type erasure
It is because of the hidden existence of type erasure that it leads directly to many generic supernatural problems.
1. Method signatures cannot be distinguished by instance of a generic class to implement method overloading
650) this.width=650; "border=" 0 "src=" http://s3.51cto.com/wyfs02/M01/80/3B/wKioL1c7827x1EHGAAAkoQPGpNM697.png " data_ue_src= "E:\My knowledge\temp\a4c39093-6982-4fa8-b727-a89d5892c097.png" >
2. Generics cannot be used in catch
650) this.width=650; "border=" 0 "src=" http://s3.51cto.com/wyfs02/M02/80/3D/wKiom1c78oSAdz3YAAAbLkTZTbE040.png " data_ue_src= "E:\My knowledge\temp\c743ce3d-e0b5-4e07-bf16-0cb2031d201f.png" >
3. Static variables for generic classes are shared
12345678910 |
public class Test {
public static void main(String[] args) {
ErasureTest<Integer> gti =
new ErasureTest<Integer>();
gti.var=
1
;
ErasureTest<String> gts =
new ErasureTest<String>();
gts.var=
2
;
System.out.println(gti.var);
System.out.println(gts.var);
}
}
|
650) this.width=650; "border=" 0 "src=" http://s3.51cto.com/wyfs02/M02/80/3B/wKioL1c7826x1Wi8AAAJQLbNDEc071.png " data_ue_src= "E:\My knowledge\temp\206b03c1-50d5-4b01-bb33-317781643351.png" >
(iii), avoid generic erase 1, when you create a generic object, specify the type
Like what
1 |
ArrayList arrayList= new ArrayList(); |
Change into
1 |
ArrayList<String> arrayList= new ArrayList<String>(); |
2, the following two kinds of wording of the difference
12 |
ArrayList<String> arrayList1= new ArrayList(); //第一种 情况 ArrayList arrayList2= new ArrayList<String>(); //第二种 情况 |
New ArrayList () simply creates a storage space in memory that can store any type object. What really involves a type check is its reference, because we use it to refer to ArrayList1 to invoke its method, such as calling the Add () method. So the ArrayList1 reference can complete the check of the generic type. The reference arrayList2 does not use generics, so no
650) this.width=650; "border=" 0 "src=" http://s3.51cto.com/wyfs02/M01/80/3D/wKiom1c78oWA16x1AAAusIvg77A880.png " data_ue_src= "E:\My knowledge\temp\577a80a0-9c86-4581-b74a-668be6a640e1.png" >
Second, the generic conversion (a) there is a generic to non-generic
When you assign an object with generic information to another variable that does not have generic information, all type information between the angle brackets is thrown away.
For example, if a list<string> type is converted to list, then the list has the type check of the collection element as the upper bound of the type variable (Object)
123456789101112 |
public class GenericTest2 {
public static void main(String[] args) {
List<Integer> li =
new ArrayList<Integer>();
li.add(
6
);
li.add(
9
);
Integer a = li.get(
0
);
//有警告:“未经检查的转换”,编译、运行时完全正常
List list = li;
//元素类型被转换成Object
Integer b = (Integer) list.get(
0
);
}
}
|
(b) Generic A cannot be turned into a generic type B
650) this.width=650; "border=" 0 "src=" http://s3.51cto.com/wyfs02/M01/80/3B/wKioL1c7826AwBz-AAAhQxkJw28591.png " data_ue_src= "E:\My knowledge\temp\b8ad875d-a440-476
Learn from teacher Wang Generics (eight): Generic Erase and transform