Jvm学习笔记(二)

Class类文件结构


Class类文件结构
  • 无符号数:u1、u2、u4、u8分别代表1个字节、2个字节、4个字节、8个字节

  • magic:魔数,4个字节,唯一取值"0xCAFEBABE"

  • minjor_version、major_version:Class文件版本号

  • constant_pool_count:由于常量池数量不固定,在常量池入口放置一2字节类型数据,代表常量池容量计数。计数从1开始。即constant_pool_count = constant_pool长度+1 。

  • constant_pool:常量池。包括字面量和符号引用。字面量指java中的字符串和final类型常量等。符号引用包括类和接口的全限定名、字段的名称和描述符、方法的名称和描述符。

常量池标志位

CONSTANT_Class_info结构里包含一个name_index,指向一个 CONSTANT_Utf8_info,为这个类的全限定名。CONSTANT_Utf8_info结构包含length,和bytes。

CONSTANT_Class_info {
    u1 tag;   //tag取值为7,代表CONSTANT_Class_info
    u2 name_index;  //name_index表示代表自己类名的字符串信息位于于常量池数组中哪一个,也就是索引
}
CONSTANT_Utf8_info {
    u1 tag;
    u2 length;  //下面就是存储UTF8字符串的地方了
    u1 bytes[length];
}
CONSTANT_NameAndType_info {
   u1 tag;
   u2 name_index;  //方法名或域名对应的字符串索引
   u2 descriptor_index; //方法信息(参数+返回值),或者成员变量的信息(类型)对应的字符串索引
}
CONSTANT_Fieldref_info {
   u1 tag;
   u2 class_index;  
   u2 name_and_type_index; 
}
CONSTANT_Methodref_info {
   u1 tag;
   u2 class_index;  
   u2 name_and_type_index;
}
CONSTANT_InterfaceMethodref_info {
   u1 tag;
   u2 class_index;  
   u2 name_and_type_index; 
}
  • access_flags:标志位。包括:这个 Class 是类还是接口,是否定义为 public 类型,abstract 类型,如果是类的话,是否声明为 final,等等。

  • this_class、super_class:类索引、父类索引。

  • interfaces、fields、methods:接口、变量、方法。

  • attributes:属性表。


示例:

public class TestMain{
    public int x = 0;

    public static void main (String [] args){
        TestMain testMain = new TestMain();
        testMain.test();
    }

    public TestMain(){

    }
    public void test(){
        
    }
}

javap -verbose

public class TestMain                                                                 
  minor version: 0                                                                    
  major version: 52                                                                   
  flags: ACC_PUBLIC, ACC_SUPER                                                        
Constant pool:                                                                        
   #1 = Class              #18            // TestMain                                 
   #2 = Methodref          #1.#19         // TestMain."<init>":()V                    
   #3 = Methodref          #1.#20         // TestMain.test:()V                        
   #4 = Methodref          #6.#19         // java/lang/Object."<init>":()V            
   #5 = Fieldref           #1.#21         // TestMain.x:I                             
   #6 = Class              #22            // java/lang/Object                         
   #7 = Utf8               x                                                          
   #8 = Utf8               I                                                          
   #9 = Utf8               main                                                       
  #10 = Utf8               ([Ljava/lang/String;)V                                     
  #11 = Utf8               Code                                                       
  #12 = Utf8               LineNumberTable                                            
  #13 = Utf8               <init>                                                     
  #14 = Utf8               ()V                                                        
  #15 = Utf8               test                                                       
  #16 = Utf8               SourceFile                                                 
  #17 = Utf8               TestMain.java                                              
  #18 = Utf8               TestMain                                                   
  #19 = NameAndType        #13:#14        // "<init>":()V                             
  #20 = NameAndType        #15:#14        // test:()V                                 
  #21 = NameAndType        #7:#8          // x:I                                      
  #22 = Utf8               java/lang/Object                                           
{                                                                                     
  public int x;                                                                       
    descriptor: I                                                                     
    flags: ACC_PUBLIC                                                                 
                                                                                      
  public static void main(java.lang.String[]);                                        
    descriptor: ([Ljava/lang/String;)V                                                
    flags: ACC_PUBLIC, ACC_STATIC                                                     
    Code:                                                                             
      stack=2, locals=2, args_size=1                                                  
         0: new           #1                  // class TestMain                       
         3: dup                                                                       
         4: invokespecial #2                  // Method "<init>":()V                  
         7: astore_1                                                                  
         8: aload_1                                                                   
         9: invokevirtual #3                  // Method test:()V                      
        12: return                                                                    
      LineNumberTable:                                                                
        line 5: 0                                                                     
        line 6: 8                                                                     
        line 7: 12                                                                    
                                                                                      
  public TestMain();                                                                  
    descriptor: ()V                                                                   
    flags: ACC_PUBLIC                                                                 
    Code:                                                                             
      stack=2, locals=1, args_size=1                                                  
         0: aload_0                                                                   
         1: invokespecial #4                  // Method java/lang/Object."<init>":()V 
         4: aload_0                                                                   
         5: iconst_0                                                                  
         6: putfield      #5                  // Field x:I                            
         9: return                                                                    
      LineNumberTable:                                                                
        line 9: 0                                                                     
        line 2: 4                                                                     
        line 11: 9                                                                    
                                                                                      
  public void test();                                                                 
    descriptor: ()V                                                                   
    flags: ACC_PUBLIC                                                                 
    Code:                                                                             
      stack=0, locals=1, args_size=1                                                  
         0: return                                                                    
      LineNumberTable:                                                                
        line 14: 0                                                                    
}                                                                                     
SourceFile: "TestMain.java"                                                           
                                                                                      
  • 如上,在常量池中,第一个元素为Class,即CONSTANT_Class_info,它的name_index为第18个元素,即Utf8_info,内容为字符串"TestMain"。第二个元素为Methodref_info,其class_index为第一个元素,即"TestMain",name_and_type_index为第19个元素,对应第13个元素和第14个元素,V代表void。以此类推。

  • Code属性:

    • stack=2,locals=2,args_size=1。结合代码,main函数确实有一个参数,而且还有一个本地变量。注意,main函数是static的。如果对于类的非static函数,那么locals的第0个元素代表this。stack表示操作数最大栈深度。locals表示局部变量所需要的空间,以slot为单位。args_size参数个数。
    • stack后面接下来的就是code数组,也就是这个函数对应的执行代码。0表示code[]的索引位置。0:new:代表这个操作是new操作,此操作对应的字节码长度为3,所以下一个操作对应的字节码从索引3开始。
    • LineNumberTable:也是属性的一种,用于调试,它将源码和字节码匹配了起来。比如line 5: 0这句话代表该函数字节码0那一个操作对应代码的第5行。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容