1. 程式人生 > 其它 >java泛型資訊儲存在哪裡

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;>;;

因此,來自常量池的資訊用於表示一個欄位是一個通用型別。