深入理解Java虛擬機(jī)之Class文件結(jié)構(gòu)

Class類文件結(jié)構(gòu):

  • Class文件是一組以8字節(jié)為基礎(chǔ)單位的二進(jìn)制流,
  • 各個數(shù)據(jù)項目嚴(yán)格按照順序緊湊排列在class文件中老充,
  • 中間沒有任何分隔符衔彻,這使得class文件中存儲的內(nèi)容幾乎是全部程序運(yùn)行的程序尘盼。

Java虛擬機(jī)規(guī)范規(guī)定,Class文件格式采用類似C語言結(jié)構(gòu)體的偽結(jié)構(gòu)來存儲數(shù)據(jù)兼吓,這種結(jié)構(gòu)只有兩種數(shù)據(jù)類型:無符號數(shù)和表臂港。

無符號數(shù)

屬于基本數(shù)據(jù)類型,主要可以用來描述數(shù)字视搏、索引符號审孽、數(shù)量值或者按照UTF-8編碼構(gòu)成的字符串值,大小使用u1浑娜、u2佑力、u4、u8分別表示1字節(jié)筋遭、2字節(jié)打颤、4字節(jié)和8字節(jié)暴拄。

是由多個無符號數(shù)或者其他表作為數(shù)據(jù)項構(gòu)成的復(fù)合數(shù)據(jù)類型,所有的表都習(xí)慣以“_info”結(jié)尾编饺。表主要用于描述有層次關(guān)系的復(fù)合結(jié)構(gòu)的數(shù)據(jù)乖篷,比如方法、字段透且。需要注意的是class文件是沒有分隔符的那伐,所以每個的二進(jìn)制數(shù)據(jù)類型都是嚴(yán)格定義的。具體的順序定義如下:


image.png

魔數(shù)

  1. 每個Class文件的頭4個字節(jié)稱為魔數(shù)(Magic Number)
  2. 唯一作用是用于確定這個文件是否為一個能被虛擬機(jī)接受的Class文件石蔗。
  3. Class文件魔數(shù)的值為0xCAFEBABE罕邀。如果一個文件不是以0xCAFEBABE開頭,那它就肯定不是Java class文件养距。

很多文件存儲標(biāo)準(zhǔn)中都使用魔數(shù)來進(jìn)行身份識別诉探,譬如圖片格式,如gif或jpeg等在文件頭中都存有魔數(shù)棍厌。使用魔術(shù)而不是使用擴(kuò)展名是基于安全性考慮的——擴(kuò)展名可以隨意被改變!!!
例如:


image.png

Class文件的版本號

緊接著魔數(shù)的4個字節(jié)是Class文件版本號肾胯,版本號又分為:

  1. 次版本號(minor_version): 前2字節(jié)用于表示次版本號
  2. 主版本號(major_version): 后2字節(jié)用于表示主版本號。

這個的版本號是隨著jdk版本的不同而表示不同的版本范圍的耘纱。Java的版本號是從45開始的敬肚。如果Class文件的版本號超過虛擬機(jī)版本,將被拒絕執(zhí)行束析。

  0X0034(對應(yīng)十進(jìn)制的50):JDK1.8      
  0X0033(對應(yīng)十進(jìn)制的50):JDK1.7      
  0X0032(對應(yīng)十進(jìn)制的50):JDK1.6      
  0X0031(對應(yīng)十進(jìn)制的49):JDK1.5  
  0X0030(對應(yīng)十進(jìn)制的48):JDK1.4  
  0X002F(對應(yīng)十進(jìn)制的47):JDK1.3  
  0X002E(對應(yīng)十進(jìn)制的46):JDK1.2 
  ps:0X表示16進(jìn)制
image.png

即:


image.png

常量池

緊接著魔數(shù)與版本號之后的是常量池入口.常量池簡單理解為class文件的資源從庫

  1. 是Class文件結(jié)構(gòu)中與其它項目關(guān)聯(lián)最多的數(shù)據(jù)類型
  2. 是占用Class文件空間最大的數(shù)據(jù)項目之一
  3. 是在文件中第一個出現(xiàn)的表類型數(shù)據(jù)項目

由于常量池中常量的數(shù)量是不固定的艳馒,所以在常量池的入口需要放置一項u2類型的數(shù)據(jù),代表常量池容量計數(shù)值(constant_pool_count)员寇。
從1開始計數(shù)弄慰。Class文件結(jié)構(gòu)中只有常量池的容量計數(shù)是從1開始的,第0項騰出來滿足后面某些指向常量池的索引值的數(shù)據(jù)在特定情況下需要表達(dá)"不引用任何一個常量池項目"的意思蝶锋,這種情況就可以把索引值置為0來表示(留給JVM自己用的)陆爽。但盡管constant_pool列表中沒有索引值為0的入口,缺失的這一入口也被constant_pool_count計數(shù)在內(nèi)扳缕。例如慌闭,當(dāng)constant_pool中有14項,constant_poo_count的值為15躯舔。
常量池之中主要存放兩大類常量:

  1. 字面量: 比較接近于Java語言層面的常量概念驴剔,如文本字符串、被聲明為final的常量值等
  2. 符號引用: 屬于編譯原理方面的概念庸毫,包括了下面三類常量:
    • 類和接口的全限定名
    • 字段的名稱和描述符
    • 方法的名稱和描述符

constant_pool_count:占2字節(jié)仔拟,常量池的計數(shù)是從1開始的,其它集合類型均從0開始飒赃,索引值為1~n利花。第0項常量具有特殊意義科侈,如果某些指向常量池索引值的數(shù)據(jù)在特定情況下需要表達(dá)“不引用任何一個常量池項目”的含義,這種情況可以將索引值置為0來表示

constant_pool:表類型數(shù)據(jù)集合炒事,即常量池中每一項常量都是一個表臀栈,共有14種(JDK1.7前只有11種)結(jié)構(gòu)各不相同的表結(jié)構(gòu)數(shù)據(jù)。這14種表都有一個共同的特點挠乳,即均由一個u1類型的標(biāo)志位開始权薯,可以通過這個標(biāo)志位來判斷這個常量屬于哪種常量類型,常量類型及其數(shù)據(jù)結(jié)構(gòu)如下表所示:


image.png

ps:
這14種表都有一個共同的特點睡扬,就是表開始的第一位是一個u1類型的標(biāo)識位盟蚣,取值見上表,代表當(dāng)前這個常量屬于哪種常量類型卖怜。

例如:

image.png

常量池的計數(shù)是從1開始的,這就代表常量池中有28項常量

0A:
CONSTANT_Methodref_info (類中方法的符號引用)


image.png

0x0006 #6---指向常量池#6號索引
0x000F #15---指向常量池#15號索引

09:
CONSTANT_Fieldref (對一個字段的符號引用)


image.png

0x0010 #16---指向常量池#16號索引
0x0011 #17---指向常量池#17號索引
通過命令即可驗證

javap -verbose HelloTest.class
Classfile /Users/liuboyu/Desktop/HelloTest.class
  Last modified 2018-9-7; size 426 bytes
  MD5 checksum 3820cf8768d7c58bbf1e4242cf82dd18
  Compiled from "HelloTest.java"
public class HelloTest
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #6.#15         // java/lang/Object."<init>":()V
   #2 = Fieldref           #16.#17        // java/lang/System.out:Ljava/io/PrintStream;
   #3 = String             #18            // Hello world!!!
   #4 = Methodref          #19.#20        // java/io/PrintStream.println:(Ljava/lang/String;)V
   #5 = Class              #21            // HelloTest
   #6 = Class              #22            // java/lang/Object
   #7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               main
  #12 = Utf8               ([Ljava/lang/String;)V
  #13 = Utf8               SourceFile
  #14 = Utf8               HelloTest.java
  #15 = NameAndType        #7:#8          // "<init>":()V
  #16 = Class              #23            // java/lang/System
  #17 = NameAndType        #24:#25        // out:Ljava/io/PrintStream;
  #18 = Utf8               Hello world!!!
  #19 = Class              #26            // java/io/PrintStream
  #20 = NameAndType        #27:#28        // println:(Ljava/lang/String;)V
  #21 = Utf8               HelloTest
  #22 = Utf8               java/lang/Object
  #23 = Utf8               java/lang/System
  #24 = Utf8               out
  #25 = Utf8               Ljava/io/PrintStream;
  #26 = Utf8               java/io/PrintStream
  #27 = Utf8               println
  #28 = Utf8               (Ljava/lang/String;)V
{
  public HelloTest();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 1: 0

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #3                  // String Hello world!!!
         5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
      LineNumberTable:
        line 3: 0
        line 4: 8
}
SourceFile: "HelloTest.java"

訪問標(biāo)志(2字節(jié))

常量池之后的數(shù)據(jù)結(jié)構(gòu)是訪問標(biāo)志(access_flags),這個標(biāo)志主要用于識別一些類或接口層次的訪問信息屎开,主要包括:


image.png

例如:


image.png

查看我們的字節(jié)碼文件,可以得知


image.png

標(biāo)識位為:ACC_PUBLIC 马靠,ACC_SUPER
驗證結(jié)果:


image.png

類索引沮焕、父類索引和接口索引集合

這三項數(shù)據(jù)主要用于確定這個類的繼承關(guān)系除秀。
其中類索引(this_class)和父類索引(super_class)都是一個u2類型的數(shù)據(jù)匈仗,而接口索引(interface)集合是一組u2類型的數(shù)據(jù)供炎。(多實現(xiàn)單繼承)

類索引(this_class)

用于確定這個類的全限定名,占2字節(jié)

父類索引(super_class)

用于確定這個類父類的全限定名(Java語言不允許多重繼承妙啃,故父類索引只有一個档泽。除了java.lang.Object類之外所有類都有父類,故除了java.lang.Object類之外彬祖,所有類該字段值都不為0)茁瘦,占2字節(jié)

接口索引計數(shù)器(interfaces_count)

占2字節(jié)品抽。如果該類沒有實現(xiàn)任何接口储笑,則該計數(shù)器值為0,并且后面的接口的索引集合將不占用任何字節(jié)圆恤,
接口索引集合(interfaces)突倍,一組u2類型數(shù)據(jù)的集合。用來描述這個類實現(xiàn)了哪些接口盆昙,這些被實現(xiàn)的接口將按implements語句(如果該類本身為接口羽历,則為extends語句)后的接口順序從左至右排列在接口的索引集合中
this_class、super_class與interfaces按順序排列在訪問標(biāo)志之后淡喜,它們中保存的索引值均指向常量池中一個CONSTANT_Class_info類型的常量秕磷,通過這個常量中保存的索引值可以找到定義在CONSTANT_Utf8_info類型的常量中的全限定名字符串


image.png

在我們的例子中:


image.png

0x0005:指向常量池 #5
0x0006:指向常量池 #6
0x0000:沒有接口


image.png

一目了然~
類的全限定名:HelloTest
父類的全限定名:java/lang/Object

字段表集合

fields_count:字段表計數(shù)器,即字段表集合中的字段表數(shù)據(jù)個數(shù)炼团,占2字節(jié)澎嚣。
fields:字段表集合疏尿,一組字段表類型數(shù)據(jù)的集合。字段表用于描述接口或類中聲明的變量易桃,包括類級別(static)和實例級別變量褥琐,不包括在方法內(nèi)部聲明的變量
在Java中一般通過如下幾項描述一個字段:字段作用域(public、protected晤郑、private修飾符)敌呈、是類級別變量還是實例級別變量(static修飾符)、可變性(final修飾符)造寝、并發(fā)可見性(volatile修飾符)磕洪、可序列化與否(transient修飾符)、字段數(shù)據(jù)類型(基本類型诫龙、對象褐鸥、數(shù)組)以及字段名稱。在字段表中赐稽,變量修飾符使用標(biāo)志位表示叫榕,字段數(shù)據(jù)類型和字段名稱則引用常量池中常量表示。


image.png
  • access_flags:是一個 u2的數(shù)據(jù)類型姊舵。
  • name_index 索引值: 對常量池的引用晰绎,代表著字段的簡單名稱。
  • descriptor_index 索引值: 對常量池的引用括丁,代表字段和方法的描述符荞下。

重新寫個有字段的類作為例子講解。


image.png
image.png
image.png

0x0003: fields_count(字段表數(shù)量)說明有三個字端表

  1. access_flags:0x0009 ---- public static
    name_index 索引值: 0x000A ---- 指向常量池#10
    descriptor_index 索引值:0x000B --- 指向常量池#11
    attributes_count 屬性表:0x0000 --- 沒有屬性表
    證明:


    image.png

則該字段的 name_index 索引值: 0x000A ---- 名字為a
則該字段的 descriptor_index 索引值:0x000B --- I類型,由下圖可知史飞,該類型為int類型


image.png
  1. access_flags:0x0002 ---- private
    name_index 索引值: 0x000C ---- 指向常量池#12
    descriptor_index 索引值:0x000D --- 指向常量池#13
    attributes_count 屬性表:0x0000 --- 沒有屬性表


    image.png

所以該字段為:

private String str;
  1. access_flags:0x0001 ---- public
    name_index 索引值: 0x000E ---- 指向常量池#14
    descriptor_index 索引值:0x000F --- 指向常量池#15
    attributes_count 屬性表:0x0000 --- 沒有屬性表
    所以該字段為:
public double d

方法表集合

methods_count:方法表計數(shù)器尖昏,即方法表集合中的方法表數(shù)據(jù)個數(shù)。占2字節(jié)
methods:方法表集合构资,一組方法表類型數(shù)據(jù)的集合抽诉。方法表結(jié)構(gòu)和字段表結(jié)構(gòu)一樣。

JVM中堆方法表的描述與字段表是一致的吐绵,包括了:訪問標(biāo)志迹淌、名稱索引、描述符索引己单、屬性表集合唉窃。方法表的結(jié)構(gòu)與字段表是一致的,區(qū)別在于訪問標(biāo)志的不同纹笼。在方法中不能用volatile和transient關(guān)鍵字修飾纹份,所以這兩個標(biāo)志不能用在方法表中。在方法中添加了字段不能使用的訪問標(biāo)志廷痘,比如方法可以使用synchronized蔓涧、native削咆、strictfp、abstract關(guān)鍵字修飾蠢笋,所以在方法表中就增加了相應(yīng)的訪問標(biāo)志拨齐。
要注意的是,如果父類方法沒有在子類中重寫昨寞,那么在方法中不會自動出現(xiàn)來自父類的方法信息瞻惋。同樣的,有可能添加編譯器自動增加的方法援岩,比如方法歼狼。


image.png

該示例一共有三個方法:init(自帶構(gòu)造器),main,add


image.png

方法1: init方法(構(gòu)造器方法)
0x0001: ACC_PUBLIC
0x0010: 指向常量池#16,查看上面文件可知 #16 = Utf8 <init>
0x0011: 指向常量池#17享怀,查看上面文件可知 #17 = Utf8 ()V羽峰,為 void
0x0001: 有一個屬性
0x0012: 指向常量池#18,查看上面文件可知#18 = Utf8 Code添瓷,說明此屬性是方法的字節(jié)碼描述

main,add方法同理梅屉,下面我們看一下code屬性

屬性表集合

在 Class 文件、字段表鳞贷、方法表都可以攜帶子機(jī)的屬性表集合坯汤,以用于描述某些場景專有的信息。
與 Class 文件中其他的數(shù)據(jù)項目要求嚴(yán)格的順序搀愧、長度和內(nèi)容不同惰聂,屬性表集合的限制稍微寬松了一些,不再要求各個屬性表具有嚴(yán)格順序咱筛,并且只要不與已有屬性名重復(fù)搓幌,任何人實現(xiàn)的編譯器都可以向?qū)傩员碇袑懭胱约憾x的屬性信息,
Java 虛擬機(jī)運(yùn)行時會忽略掉它不認(rèn)識的屬性迅箩。為了能正確解析 Class 文件溉愁,《Java 虛擬機(jī)規(guī)范(第 2 版)》中預(yù)定義了 9 項虛擬機(jī)實現(xiàn)應(yīng)當(dāng)能識別的屬性,而在最新的《Java 虛擬機(jī)規(guī)范(Java SE 7)》版中沙热,
預(yù)定義屬性已經(jīng)增加到 21 項叉钥,具體內(nèi)容見表下表

image.png

對于每個屬性篙贸,它的名稱需要從常量池中引用一個 CONSTANT_Utf8_info 類型的常量來表示,而屬性值的結(jié)構(gòu)則是完全自定義的枫疆,只需要通過一個 u4 的長度屬性去說明屬性值所占用的位數(shù)即可爵川。一個符合規(guī)則的屬性表應(yīng)該滿足下表中所定義的結(jié)構(gòu)。


image.png
Code屬性

Java程序方法體中的代碼經(jīng)過Javac編譯器處理后息楔,最終變?yōu)樽止?jié)碼指令存儲在Code屬性內(nèi)寝贡。Code屬性出現(xiàn)在方法表的屬性集合中扒披,但并非所有的方法都不許存在這個屬性,譬如接口或者抽象類中的方法就不存在Code屬性圃泡,如果
方法表有Code屬性存在碟案,那么它的結(jié)構(gòu)如表所示。


image.png

attribute_name_index 是一項指向 CONSTANT_Utf8_info 型常量的索引颇蜡,常量值固定為“Code”价说,它代表了該屬性的屬性名稱,attribute_length 指示了屬性值的長度风秤,由于屬性名稱索引與屬性長度一共為 6 字節(jié)鳖目,所以屬性值的長度固定為整個屬性表長度減去 6 個字節(jié)。
   max_stack 代表了操作數(shù)棧(Operand Stacks)深度的最大值缤弦。在方法執(zhí)行的任意時刻领迈,操作數(shù)棧都不會超過這個深度。虛擬機(jī)運(yùn)行的時候需要根據(jù)這個值來分配棧幀(Stack Frame)中的操作棧深度碍沐。
   max_locals 代表了局部變量表所需的存儲空間狸捅,在這里,max_locals 的單位是 Slot累提,Slot 是虛擬機(jī)為局部變量分配內(nèi)存所使用的最小單位薪贫。對于 byte、char刻恭、float瞧省、int、short鳍贾、boolean 和 returnAddress 等長度不超過 32 位的數(shù)據(jù)類型鞍匾,每個局部變量占用 1 個 Slot,
而 double 和 long 這兩種 64 位的數(shù)據(jù)類型則需要兩個 Slot 來存放骑科。方法參數(shù)(包括實例方法中的隱藏參數(shù) “this”)橡淑、顯式異常處理器的參數(shù)(Exception Handler Parameter,就是 try-catch 語句中 catch 塊所定義的異常)咆爽、方法體中定義的局部變量都需要使用局部變量表來存放梁棠。
另外,并不是在方法中用到了多少個局部變量斗埂,就把這些局部變量所占 Slot 之和作為 max_locals 的值符糊,原因是局部變量表中的 Slot 可以重寫,當(dāng)代碼執(zhí)行超出一個局部變量的作用域時呛凶,這個局部變量所占的 Slot 可以被其他局部變量所使用男娄,
Javac 編譯器會根據(jù)變量的作用域來分配 Slot 給各個變量使用,然后計算出 max_locals 的大小。
   code_length 和 code 用來存儲 Java 源程序編譯后生成的字節(jié)碼指令模闲。code_length 代表字節(jié)碼長度,code 是用于存儲字節(jié)碼指令的一系列字節(jié)流尸折。既然叫字節(jié)碼指令啰脚,那么每個指令就是一個 u1 類型的單字節(jié),當(dāng)虛擬機(jī)讀取到 code 中的一個字節(jié)碼時实夹,
就可以對應(yīng)找出這個字節(jié)碼代表的是什么指令橄浓,并且可以知道到這條指令后面是否需要跟隨參數(shù),以及參數(shù)應(yīng)當(dāng)如何理解收擦。我們知道一個 u1 數(shù)據(jù)類型的取值范圍為 0x00 ~ 0xFF贮配,對應(yīng)十進(jìn)制的 0 ~ 255,也就是一共可以表達(dá) 256 條指令塞赂,目前泪勒,Java 虛擬機(jī)規(guī)范已經(jīng)定義了其中約 200 條編碼值對應(yīng)的指令含義。
   關(guān)于 code_length宴猾,有一件值得注意的事情圆存,雖然它是一個 u4 類型的長度值,理論上最大值可以達(dá)到 2^23-1仇哆,但是虛擬機(jī)規(guī)范中明確限制了一個方法不允許超過65535 條字節(jié)碼指令沦辙,即它實際只使用了 u2 的長度,如果超過這個限制讹剔,Javac 編譯器也會拒絕編譯油讯。一般來講,編寫 Java 代碼時只要不是刻意去編寫一個超長的方法來為難編譯器延欠,是不太可能超過這個最大值的限制陌兑。但是,某些特殊情況由捎,例如在編譯一個很復(fù)雜的 JSP 文件時兔综,某些 JSP 編譯會把 JSP 內(nèi)容和頁面輸出的信息歸并于一個方法之中,就可能因為方法生成字節(jié)碼超長的原因而導(dǎo)致編譯失敗狞玛。
   Code 屬性是 Class 文件中最重要的一個屬性软驰,如果把一個 Java 程序中的信息分為代碼(Code,方法體里面的 Java 代碼)和元數(shù)據(jù)(Metadata心肪,包括類锭亏、字段、方法定義及其他信息)量部分蒙畴,那么在整個 Class 文件中贰镣,Code 屬性用于描述代碼呜象,所有的其他數(shù)據(jù)項目都用于描述元數(shù)據(jù)膳凝。了解 Code 屬性是學(xué)習(xí)后面關(guān)于字節(jié)碼執(zhí)行引擎內(nèi)容的必要基礎(chǔ)碑隆,能直接閱讀字節(jié)碼也是工作中分析 Java 代碼語義問題的必要工具和基本技能,因此筆者準(zhǔn)備了一個比較詳細(xì)的實例來講解虛擬機(jī)是如何使用這個屬性的蹬音。

繼續(xù)以上面的代碼清單 HelloTest.class 文件為例上煤,如下圖所示

  
image.png

前面6個字節(jié)(名稱索引2字節(jié)+屬性長度4字節(jié))已經(jīng)解析過了,所以接下來就是解析剩下的56-6=50字節(jié)即可著淆。
max_stack:0x0003 操作數(shù)棧的最大深度3
max_locals:0x0001 本地變量表的容量1
code_length:0x0000 000C == 12,字節(jié)碼區(qū)域所占空間的長度12
虛擬機(jī)讀取到字節(jié)碼區(qū)域的長度后劫狠,按照順序依次讀入緊隨的 12 個字節(jié),并根據(jù)字節(jié)碼指令表翻譯出所對應(yīng)的字節(jié)碼指令永部。翻譯“2A B7 00 01 2A 14 00 02 B5 00 04 B1”

code代碼独泞,可以通過虛擬機(jī)字節(jié)碼指令進(jìn)行查找。
Java字節(jié)碼指令

  1. 0x2A : aload_0 將引用類型本地變量推送至棧頂
  2. 0xB7 : invokespecial 調(diào)用超類構(gòu)造方法苔埋,實例初始化方法懦砂,私有方法
  3. 0x00 : 什么都不做
  4. 0x01 : aconst_null 將null推送至棧頂
  5. 0x2A : aload_0 將引用類型本地變量推送至棧頂
  6. 0x14 : ldc2_w 將long或do le型常量值從常量池中推送至棧頂(寬索引)
  7. 0x00 : 什么都不做
  8. 0x02 : iconst_m1 將int型-1推送至棧頂
  9. 0xB5 : putfield 為指定的類的實例域賦值
  10. 0x00 : 什么都不做
  11. 0x04 : iconst_1 將int型1推送至棧頂
  12. 0xB1 : return 從當(dāng)前方法返回void

對照用javap命令計算機(jī)字節(jié)碼指令生成的代碼,我們分析的很正確~

 Code:
      stack=3, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: aload_0
         5: ldc2_w        #2                  // double 1.2d
         8: putfield      #4                  // Field d:D
        11: return
      LineNumberTable:
        line 2: 0
        line 5: 4

意外收獲:

image.png

做android開發(fā)的同學(xué)可能有遇到過 65535 這個問題组橄,看了jvm發(fā)現(xiàn)method_countde 最大值是兩個字節(jié)的數(shù)量也就是0xFFFF,即65535

ps:

本文為小弟本人所理解荞膘,如果不對的地方,忘多多指正玉工,共同進(jìn)步~~~謝謝大家

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末羽资,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子遵班,更是在濱河造成了極大的恐慌屠升,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件狭郑,死亡現(xiàn)場離奇詭異腹暖,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)愿阐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進(jìn)店門微服,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人缨历,你說我怎么就攤上這事以蕴。” “怎么了辛孵?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵丛肮,是天一觀的道長。 經(jīng)常有香客問我魄缚,道長宝与,這世上最難降的妖魔是什么焚廊? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮习劫,結(jié)果婚禮上咆瘟,老公的妹妹穿的比我還像新娘。我一直安慰自己诽里,他們只是感情好袒餐,可當(dāng)我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著谤狡,像睡著了一般灸眼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上墓懂,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天焰宣,我揣著相機(jī)與錄音,去河邊找鬼捕仔。 笑死匕积,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的逻澳。 我是一名探鬼主播闸天,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼斜做!你這毒婦竟也來了苞氮?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤瓤逼,失蹤者是張志新(化名)和其女友劉穎笼吟,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體霸旗,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡贷帮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了诱告。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片撵枢。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖精居,靈堂內(nèi)的尸體忽然破棺而出锄禽,到底是詐尸還是另有隱情,我是刑警寧澤靴姿,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布沃但,位于F島的核電站,受9級特大地震影響佛吓,放射性物質(zhì)發(fā)生泄漏宵晚。R本人自食惡果不足惜垂攘,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望淤刃。 院中可真熱鬧晒他,春花似錦、人聲如沸钝凶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽耕陷。三九已至,卻和暖如春据沈,著一層夾襖步出監(jiān)牢的瞬間哟沫,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工锌介, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留嗜诀,地道東北人。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓孔祸,卻偏偏與公主長得像隆敢,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子崔慧,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容