• java泛型信息保存在哪里


    java泛型信息保存在哪

    jvm

    Java泛型确实通过类型擦除来实现,所以字节码中没有类型信息。

    例如,让我们看看两个声明List字段的类,一个是泛型​​的,另一个是非泛型的:

    class NonGeneric {
        List list;
    }
    

    和,

    class Generic {
        List<String> list;
    }
    

    在这两种情况下,生成的字节码如下所示:

      Code:
       Stack=3, Locals=1, Args_size=1
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   aload_0
       5:   new #2; //class java/util/ArrayList
       8:   dup
       9:   invokespecial   #3; //Method java/util/ArrayList."<init>":()V
       12:  putfield    #4; //Field list:Ljava/util/List;
       15:  return
    

    没有提及StringArrayListnor中使用的类型List。所以,我们可以看到泛型确实是通过类型擦除来实现的。

    但是,如果我们看一下常量池,我们可以找到一个区别。

    非泛型常量池:

      Constant pool:
    const #1 = Method   #6.#15; //  java/lang/Object."<init>":()V
    const #2 = class    #16;    //  java/util/ArrayList
    const #3 = Method   #2.#15; //  java/util/ArrayList."<init>":()V
    const #4 = Field    #5.#17; //  NonGeneric.list:Ljava/util/List;
    const #5 = class    #18;    //  NonGeneric
    const #6 = class    #19;    //  java/lang/Object
    const #7 = Asciz    list;
    const #8 = Asciz    Ljava/util/List;;
    const #9 = Asciz    <init>;
    const #10 = Asciz   ()V;
    // snip the rest //
    

    通用常量池:

      Constant pool:
    const #1 = Method   #6.#17; //  java/lang/Object."<init>":()V
    const #2 = class    #18;    //  java/util/ArrayList
    const #3 = Method   #2.#17; //  java/util/ArrayList."<init>":()V
    const #4 = Field    #5.#19; //  Generic.list:Ljava/util/List;
    const #5 = class    #20;    //  Generic
    const #6 = class    #21;    //  java/lang/Object
    const #7 = Asciz    list;
    const #8 = Asciz    Ljava/util/List;;
    const #9 = Asciz    Signature;
    const #10 = Asciz   Ljava/util/List<Ljava/lang/String;>;;
    const #11 = Asciz   <init>;
    const #12 = Asciz   ()V;
    // snip the rest//
    

    可以看出,在Generic该类中,我们可以看到有两个额外的常量,#9并且#10在常量池中提到了List具有泛型类型String

    (并结合我从Chris Jester-Young的回答中学到的新知识)

    在类文件的拆卸展望更远的,还有前右为恒定#10参考Code: block的的Generic类:

    java.util.List list;
      Signature: length = 0x2
       00 0A 
    

    十六进制值0A10十进制的,它是指常量池#10

    const #10 = Asciz   Ljava/util/List<Ljava/lang/String;>;;
    

    因此,来自常量池的信息用于表示一个字段是一个通用类型。

  • 相关阅读:
    MeshLab编译理解
    几个经典的数学库之一学习---VCGlib(1)
    开源协议的几种类型认识
    Win & Mac 系统之间U盘传递的U盘文件格式选取问题
    用VS2010编译python2.7的源码
    类之间关系理解:组合>聚合>关联>依赖;实现,继承
    Linux进阶:让效率翻倍的Bash技巧(一)
    Linux下nc命来实现文件传输
    nginx 405 not allowed问题的解决
    vim同时打开多个文件进行编辑
  • 原文地址:https://www.cnblogs.com/sunupo/p/16005617.html
Copyright © 2020-2023  润新知