class字节码文件

写在前面的话

class文件结构可以说是一套规范,不一定是Java编译器编译出来的版本,它用来描述一个文件中对应的字段,类,常量池,继承关系等等。值得一提的是这个文件是完全紧凑型的。从第一个字节到最后一个字节,表达的意思按照约定好的严格规范。由于这种字节码可以运行在jvm上实现跨平台的亮点。所以不只是Java语言编译器可以编译成这种文件。class文件是学习jvm中比较重要的一环。我尽量用案例来分析一个class文件的解析。还是少一些理论性的东西.

案例源码


    package structureclass.demo;

    public class TestClass{

        private int m;

        public int inc(){
            return m+1;
        }
    }

class字节码(winhex截图)

这里写图片描述

字节码部分构成

字节数与类型名称数量
4个magic(魔数)1
2个minor_version(次版本号)1
2个major_version(主版本号)1
2个constant_pool_count(常量池数量,从1开始)1
cp_infoconstant_pool(常量池)constant_pool_count - 1
2个constant_pool_count(常量池数量,从1开始)1
2个access_flags(访问标志)1
2个this_class(类索引)1
2个super_class(父类索引)1
2个interfaces_count(接口计数器)1
2个interfaces(接口描述)interfaces_count
2个fields_count(字段表集合count)1
field_infofields(字段表集合)fields_count
2个methods_count(方法表集合count)1
method_infomethods(方法表集合)methods_count
2个attributes_count(属性表集合count)1
attribute_infoattributes(属性表集合)attributes_count

class字节码文件是严格按照这个顺序占位排列的
其中_info后缀叫做为表,我们把它理解成一个数据结构即可.

magic魔数

这里写图片描述

对应位置:0+4
如图所示,标识这个文件是一个class文件,这个是严格约束的。必须是这个文件才会被识别。可以理解为后缀与魔数的唯一绑定关系。对应结果CAFE BABE

minor_version&&major_version(次版本号和主版本号)

这里写图片描述

对应位置:0+4+4
虚拟机会向下兼容其版本号,对于高于其对应版本号的文件,直接拒绝,无论格式是否正确。对应结果:JDK1.7.0。此阶段不做过多研究,安装好jdk,随意编译一下即可知道对应的版本号

constant_pool_count(常量池数量)

这里写图片描述

对应位置:0+4+4+2
constant_pool_count从1开始,所以表示的数要计算结果以后-1,
0表示不引用任何常量
16进制33等于 3*16^0+1*16^1 = 19 -1 = 18

javap -verbose 输出:

λ javap -verbose TestClass.class                                                                
Classfile /E:/jvmana/TestClass.class                                                            
  Last modified 2018-5-18; size 295 bytes                                                       
  MD5 checksum 4ee039bbc694ca6a1383cb5bebb97d19                                                 
  Compiled from "TestClass.java"                                                                
public class structureclass.demo.TestClass                                                      
  SourceFile: "TestClass.java"                                                                  
  minor version: 0                                                                              
  major version: 51                                                                             
  flags: ACC_PUBLIC, ACC_SUPER                                                                  
Constant pool:                                                                                  
   #1 = Methodref          #4.#15         //  java/lang/Object."<init>":()V                     
   #2 = Fieldref           #3.#16         //  structureclass/demo/TestClass.m:I                 
   #3 = Class              #17            //  structureclass/demo/TestClass                     
   #4 = Class              #18            //  java/lang/Object                                  
   #5 = Utf8               m                                                                    
   #6 = Utf8               I                                                                    
   #7 = Utf8               <init>                                                               
   #8 = Utf8               ()V                                                                  
   #9 = Utf8               Code                                                                 
  #10 = Utf8               LineNumberTable                                                      
  #11 = Utf8               inc                                                                  
  #12 = Utf8               ()I                                                                  
  #13 = Utf8               SourceFile                                                           
  #14 = Utf8               TestClass.java                                                       
  #15 = NameAndType        #7:#8          //  "<init>":()V                                      
  #16 = NameAndType        #5:#6          //  m:I                                               
  #17 = Utf8               structureclass/demo/TestClass                                        
  #18 = Utf8               java/lang/Object                                                     
{                                                                                               
  public structureclass.demo.TestClass();                                                       
    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 3: 0                                                                               

  public int inc();                                                                             
    flags: ACC_PUBLIC                                                                           
    Code:                                                                                       
      stack=2, locals=1, args_size=1                                                            
         0: aload_0                                                                             
         1: getfield      #2                  // Field m:I                                      
         4: iconst_1                                                                            
         5: iadd                                                                                
         6: ireturn                                                                             
      LineNumberTable:                                                                          
        line 8: 0                                                                               
}                                                                                               

我们可以看到正好是18项常量。与我们的计算结果一致。

那么,我们继续往下看

constant_pool(静态常量池)

未完待续

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值