学过C++模板的,在使用Java泛型的时候,会感觉到有点不疑问,例如:(1)无法定义一个泛型数组、无法调用泛型参数对象中对应的方法(当然,通过extends关键字是可以做到,只是比较麻烦);(2)ArrayList<Integer>和ArrayList<String>在运行时的类型是相同的。Java中的泛型有这些问题,是它的实现机制决定的,即“类型擦除”。
- public class Holder4 < T > {
-
- private T a;
- private T b;
- private T c;
-
- public Holder4(T a, T b, T c) {
- this.a = a;
- this.b = b;
- this.c = c;
- }
-
- public T getA() {
- return a;
- }
-
- public T getB() {
- return b;
- }
-
- public T getC() {
- return c;
- }
-
- public void setA(T a) {
- this.a = a;
- }
-
- public void setB(T b) {
- this.b = b;
- }
-
- public void setC(T c) {
- this.c = c;
- }
-
- public static void main(String[] args) {
- Holder4 < Automobile > holder4 = new Holder4 < >(new Automobile(), new Automobile(), new Automobile());
-
- Automobile a = holder4.getA(); //编译器帮忙转型,不需要显式转型
- Automobile b = holder4.getB();
- Automobile c = holder4.getC();
- }
- }
在Java中,每定义一个泛型类型,就会自动提供一个对应的原始类型,例如:
- public class Holder4Raw {
-
- private Object a;
- private Object b;
- private Object c;
-
- public Holder4Raw(Object a, Object b, Object c) {
- this.a = a;
- this.b = b;
- this.c = c;
- }
-
- public Object getA() {
- return a;
- }
-
- public Object getB() {
- return b;
- }
-
- public Object getC() {
- return c;
- }
-
- public void setA(Object a) {
- this.a = a;
- }
-
- public void setB(Object b) {
- this.b = b;
- }
-
- public void setC(Object c) {
- this.c = c;
- }
-
- public static void main(String[] args) {
- Holder4Raw holder4Raw = new Holder4Raw(new Automobile(), new Automobile(), new Automobile());
-
- Automobile a = (Automobile) holder4Raw.getA(); //显示的转型
- Automobile b = (Automobile) holder4Raw.getB();
- Automobile c = (Automobile) holder4Raw.getC();
- }
- }
我们通过字节码进行观察,可以看出:(1)Holder4和Holder4Raw两个类的字节码完全相同;(2)在main函数的33、41和49行就是编译器插入的checkcast语句;
- public class org.java.learn.generics.Holder4<T> {
- public org.java.learn.generics.Holder4(T, T, T);
- Code:
- 0: aload_0
- 1: invokespecial #1 // Method java/lang/Object."<init>":()V
- 4: aload_0
- 5: aload_1
- 6: putfield #2 // Field a:Ljava/lang/Object;
- 9: aload_0
- 10: aload_2
- 11: putfield #3 // Field b:Ljava/lang/Object;
- 14: aload_0
- 15: aload_3
- 16: putfield #4 // Field c:Ljava/lang/Object;
- 19: return
-
- public T getA();
- Code:
- 0: aload_0
- 1: getfield #2 // Field a:Ljava/lang/Object;
- 4: areturn
-
- public T getB();
- Code:
- 0: aload_0
- 1: getfield #3 // Field b:Ljava/lang/Object;
- 4: areturn
-
- public T getC();
- Code:
- 0: aload_0
- 1: getfield #4 // Field c:Ljava/lang/Object;
- 4: areturn
-
- public void setA(T);
- Code:
- 0: aload_0
- 1: aload_1
- 2: putfield #2 // Field a:Ljava/lang/Object;
- 5: return
-
- public void setB(T);
- Code:
- 0: aload_0
- 1: aload_1
- 2: putfield #3 // Field b:Ljava/lang/Object;
- 5: return
-
- public void setC(T);
- Code:
- 0: aload_0
- 1: aload_1
- 2: putfield #4 // Field c:Ljava/lang/Object;
- 5: return
-
- public static void main(java.lang.String[]);
- Code:
- 0: new #5 // class org/java/learn/generics/Holder4
- 3: dup
- 4: new #6 // class org/java/learn/generics/Automobile
- 7: dup
- 8: invokespecial #7 // Method org/java/learn/generics/Automobile."<init>":()V
- 11: new #6 // class org/java/learn/generics/Automobile
- 14: dup
- 15: invokespecial #7 // Method org/java/learn/generics/Automobile."<init>":()V
- 18: new #6 // class org/java/learn/generics/Automobile
- 21: dup
- 22: invokespecial #7 // Method org/java/learn/generics/Automobile."<init>":()V
- 25: invokespecial #8 // Method "<init>":(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
- 28: astore_1
- 29: aload_1
- 30: invokevirtual #9 // Method getA:()Ljava/lang/Object;
- 33: checkcast #6 // class org/java/learn/generics/Automobile,get方法的转型
- 36: astore_2
- 37: aload_1
- 38: invokevirtual #10 // Method getB:()Ljava/lang/Object;
- 41: checkcast #6 // class org/java/learn/generics/Automobile,get方法的转型
- 44: astore_3
- 45: aload_1
- 46: invokevirtual #11 // Method getC:()Ljava/lang/Object;
- 49: checkcast #6 // class org/java/learn/generics/Automobile,get方法的转型
- 52: astore 4
- 54: return
- }
原文作者:duqicauc
转载地址:Java泛型之类型擦除 | Spring For All
来源: https://zhuanlan.zhihu.com/p/31741402