美文网首页
泛型(三)之Java如何处理泛型

泛型(三)之Java如何处理泛型

作者: 极客天空 | 来源:发表于2020-05-04 22:13 被阅读0次

揭秘泛型本质一

类型擦除.png

由此可见运行时获取的类信息是一致的,泛型信息被擦除了,只保留了原始类型信息ArrayList

揭秘泛型本质二

工欲善其事必先利其器

  1. 在AS中引入ASM
    ASM
    下载完之后 通过本地文件导入
    ASM.png
  2. 利用ASM查看译后的字节码文件
字节码文件.png
  1. 查看文件AIPlate
package fastec.com.rrcc.generics.demo02;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class AIPlate<T extends Comparable<T>> implements Plate<T>{

    private List<T> items = new ArrayList<T>(10);

    public AIPlate(){

    }

    public void set(T t) {
        items.add(t);
        Collections.sort(items);
    }

    public T get(){
        int index = items.size() -1;
        if(index>= 0){
            return items.get(index);
        }else{
            return null;
        }

    }


    @Override
    public boolean equals(Object obj) {
        return super.equals(obj);
    }

    @Override
    public String toString() {
        return "Plate{" +
                "items=" + items +
                '}';
    }
}

通过ASM查看其字节码文件

// class version 51.0 (51)
// access flags 0x21
// signature <T::Ljava/lang/Comparable<TT;>;>Ljava/lang/Object;Lfastec/com/rrcc/generics/demo02/Plate<TT;>;
// declaration: fastec/com/rrcc/generics/demo02/AIPlate<T extends java.lang.Comparable<T>> implements fastec.com.rrcc.generics.demo02.Plate<T>
public class fastec/com/rrcc/generics/demo02/AIPlate implements fastec/com/rrcc/generics/demo02/Plate {

  // compiled from: AIPlate.java

  // access flags 0x2
  // signature Ljava/util/List<TT;>;
  // declaration: items extends java.util.List<T>
  private Ljava/util/List; items

  // access flags 0x1
  public <init>()V
   L0
    LINENUMBER 13 L0
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init> ()V
   L1
    LINENUMBER 11 L1
    ALOAD 0
    NEW java/util/ArrayList
    DUP
    BIPUSH 10
    INVOKESPECIAL java/util/ArrayList.<init> (I)V
    PUTFIELD fastec/com/rrcc/generics/demo02/AIPlate.items : Ljava/util/List;
   L2
    LINENUMBER 15 L2
    RETURN
   L3
    LOCALVARIABLE this Lfastec/com/rrcc/generics/demo02/AIPlate; L0 L3 0
    // signature Lfastec/com/rrcc/generics/demo02/AIPlate<TT;>;
    // declaration: this extends fastec.com.rrcc.generics.demo02.AIPlate<T>
    MAXSTACK = 4
    MAXLOCALS = 1

  // access flags 0x1
  // signature (TT;)V
  // declaration: void set(T)
  public set(Ljava/lang/Comparable;)V
   L0
    LINENUMBER 18 L0
    ALOAD 0
    GETFIELD fastec/com/rrcc/generics/demo02/AIPlate.items : Ljava/util/List;
    ALOAD 1
    INVOKEINTERFACE java/util/List.add (Ljava/lang/Object;)Z (itf)
    POP
   L1
    LINENUMBER 19 L1
    ALOAD 0
    GETFIELD fastec/com/rrcc/generics/demo02/AIPlate.items : Ljava/util/List;
    INVOKESTATIC java/util/Collections.sort (Ljava/util/List;)V
   L2
    LINENUMBER 20 L2
    RETURN
   L3
    LOCALVARIABLE this Lfastec/com/rrcc/generics/demo02/AIPlate; L0 L3 0
    // signature Lfastec/com/rrcc/generics/demo02/AIPlate<TT;>;
    // declaration: this extends fastec.com.rrcc.generics.demo02.AIPlate<T>
    LOCALVARIABLE t Ljava/lang/Comparable; L0 L3 1
    // signature TT;
    // declaration: t extends T
    MAXSTACK = 2
    MAXLOCALS = 2

  // access flags 0x1
  // signature ()TT;
  // declaration: T get()
  public get()Ljava/lang/Comparable;
   L0
    LINENUMBER 23 L0
    ALOAD 0
    GETFIELD fastec/com/rrcc/generics/demo02/AIPlate.items : Ljava/util/List;
    INVOKEINTERFACE java/util/List.size ()I (itf)
    ICONST_1
    ISUB
    ISTORE 1
   L1
    LINENUMBER 24 L1
    ILOAD 1
    IFLT L2
   L3
    LINENUMBER 25 L3
    ALOAD 0
    GETFIELD fastec/com/rrcc/generics/demo02/AIPlate.items : Ljava/util/List;
    ILOAD 1
    INVOKEINTERFACE java/util/List.get (I)Ljava/lang/Object; (itf)
    CHECKCAST java/lang/Comparable
    ARETURN
   L2
    LINENUMBER 27 L2
   FRAME APPEND [I]
    ACONST_NULL
    ARETURN
   L4
    LOCALVARIABLE this Lfastec/com/rrcc/generics/demo02/AIPlate; L0 L4 0
    // signature Lfastec/com/rrcc/generics/demo02/AIPlate<TT;>;
    // declaration: this extends fastec.com.rrcc.generics.demo02.AIPlate<T>
    LOCALVARIABLE index I L1 L4 1
    MAXSTACK = 2
    MAXLOCALS = 2

  // access flags 0x1
  public equals(Ljava/lang/Object;)Z
   L0
    LINENUMBER 35 L0
    ALOAD 0
    ALOAD 1
    INVOKESPECIAL java/lang/Object.equals (Ljava/lang/Object;)Z
    IRETURN
   L1
    LOCALVARIABLE this Lfastec/com/rrcc/generics/demo02/AIPlate; L0 L1 0
    // signature Lfastec/com/rrcc/generics/demo02/AIPlate<TT;>;
    // declaration: this extends fastec.com.rrcc.generics.demo02.AIPlate<T>
    LOCALVARIABLE obj Ljava/lang/Object; L0 L1 1
    MAXSTACK = 2
    MAXLOCALS = 2

  // access flags 0x1
  public toString()Ljava/lang/String;
   L0
    LINENUMBER 40 L0
    NEW java/lang/StringBuilder
    DUP
    INVOKESPECIAL java/lang/StringBuilder.<init> ()V
    LDC "Plate{items="
    INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
    ALOAD 0
    GETFIELD fastec/com/rrcc/generics/demo02/AIPlate.items : Ljava/util/List;
    INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/Object;)Ljava/lang/StringBuilder;
    BIPUSH 125
    INVOKEVIRTUAL java/lang/StringBuilder.append (C)Ljava/lang/StringBuilder;
    INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
    ARETURN
   L1
    LOCALVARIABLE this Lfastec/com/rrcc/generics/demo02/AIPlate; L0 L1 0
    // signature Lfastec/com/rrcc/generics/demo02/AIPlate<TT;>;
    // declaration: this extends fastec.com.rrcc.generics.demo02.AIPlate<T>
    MAXSTACK = 2
    MAXLOCALS = 1

  // access flags 0x1041
  public synthetic bridge get()Ljava/lang/Object;
   L0
    LINENUMBER 9 L0
    ALOAD 0
    INVOKEVIRTUAL fastec/com/rrcc/generics/demo02/AIPlate.get ()Ljava/lang/Comparable;
    ARETURN
   L1
    LOCALVARIABLE this Lfastec/com/rrcc/generics/demo02/AIPlate; L0 L1 0
    // signature Lfastec/com/rrcc/generics/demo02/AIPlate<TT;>;
    // declaration: this extends fastec.com.rrcc.generics.demo02.AIPlate<T>
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x1041
  public synthetic bridge set(Ljava/lang/Object;)V
   L0
    LINENUMBER 9 L0
    ALOAD 0
    ALOAD 1
    CHECKCAST java/lang/Comparable
    INVOKEVIRTUAL fastec/com/rrcc/generics/demo02/AIPlate.set (Ljava/lang/Comparable;)V
    RETURN
   L1
    LOCALVARIABLE this Lfastec/com/rrcc/generics/demo02/AIPlate; L0 L1 0
    // signature Lfastec/com/rrcc/generics/demo02/AIPlate<TT;>;
    // declaration: this extends fastec.com.rrcc.generics.demo02.AIPlate<T>
    MAXSTACK = 2
    MAXLOCALS = 2
}

桥方法.png

父类Plate擦除之后变为,这个时候子类无法覆盖父类的方法

public abstract interface fastec/com/rrcc/generics/demo02/Plate {

  // compiled from: Plate.java

  // access flags 0x401
  // signature (TT;)V
  // declaration: void set(T)
  public abstract set(Ljava/lang/Object;)V

  // access flags 0x401
  // signature ()TT;
  // declaration: T get()
  public abstract get()Ljava/lang/Object;
}

类型擦除与多态发生了冲突,要解决这个问题,就需要在AIPlate中生成一个桥方法

三 泛型擦除的残留

类型擦除保留信息.png

查看类文件 其签名信息保留其定义的格式,这样对分析字节码文件也是有益的
泛型类独有的标记,普通类是 没有的,JDK 5 之后才加入,标记了定义时的c成员签名(泛型参数列表、参数类型、返回值等)

相关文章

  • Java泛型—Java语法糖,只在编译有作用,编译后擦出泛型

    Java泛型—Java语法糖,只在编译有作用,编译后擦出泛型 在代码进入和离开的边界处,会处理泛型 Java泛型作...

  • Java泛型教程

    Java泛型教程导航 Java 泛型概述 Java泛型环境设置 Java泛型通用类 Java泛型类型参数命名约定 ...

  • 泛型(三)之Java如何处理泛型

    揭秘泛型本质一 由此可见运行时获取的类信息是一致的,泛型信息被擦除了,只保留了原始类型信息ArrayList 揭秘...

  • java 泛型解析

    Java 泛型 1、泛型的精髓是什么 2、泛型方法如何使用 概述: 泛型在java中具有重要地位,在面向对象编程模...

  • 第二十八课:泛型

    泛型出现之前 泛型出现之后 Java深度历险(五)——Java泛型

  • 想理解泛型吗?看这一篇就够了!

    一、前言二、泛型类2.1 概述Java中泛型使用情况大致包括三种:泛型类、泛型接口、泛型方法 本节演示泛型类。 2...

  • Java泛型

    参考:Java知识点总结(Java泛型) 自定义泛型类 自定义泛型接口 非泛型类中定义泛型方法 继承泛型类 通配符...

  • Kotlin 泛型

    说起 kotlin 的泛型,就离不开 java 的泛型,首先来看下 java 的泛型,当然比较熟悉 java 泛型...

  • JAVA 泛型意淫之旅(二)

    编译器如何处理泛型 泛型类编译后长什么样? 接上文,JAVA 泛型意淫之旅1,成功迎娶白富美后,终于迎来了最振奋人...

  • java泛型中类型擦除的一些思考

    java泛型 java泛型介绍 java泛型的参数只可以代表类,不能代表个别对象。由于java泛型的类型参数之实际...

网友评论

      本文标题:泛型(三)之Java如何处理泛型

      本文链接:https://www.haomeiwen.com/subject/vniyghtx.html