JVM字节码之class结构

  • Demo

    public class Hello {
          
          
        public static void main(String[] args) {
          
          
            System.out.println("Hello,world");
        }
    }
    //对应class文件16进制,一个16进制占4位,两个16进制就是代表八位(一个字节)
    cafe babe 0000 0034 001d 0a00 0600 0f09
    0010 0011 0800 120a 0013 0014 0700 1507
    0016 0100 063c 696e 6974 3e01 0003 2829
    5601 0004 436f 6465 0100 0f4c 696e 654e
    756d 6265 7254 6162 6c65 0100 046d 6169
    6e01 0016 285b 4c6a 6176 612f 6c61 6e67
    2f53 7472 696e 673b 2956 0100 0a53 6f75
    7263 6546 696c 6501 000a 4865 6c6c 6f2e
    6a61 7661 0c00 0700 0807 0017 0c00 1800
    1901 000b 4865 6c6c 6f2c 776f 726c 6407
    001a 0c00 1b00 1c01 0005 4865 6c6c 6f01
    0010 6a61 7661 2f6c 616e 672f 4f62 6a65
    6374 0100 106a 6176 612f 6c61 6e67 2f53
    7973 7465 6d01 0003 6f75 7401 0015 4c6a
    6176 612f 696f 2f50 7269 6e74 5374 7265
    616d 3b01 0013 6a61 7661 2f69 6f2f 5072
    696e 7453 7472 6561 6d01 0007 7072 696e
    746c 6e01 0015 284c 6a61 7661 2f6c 616e
    672f 5374 7269 6e67 3b29 5600 2100 0500
    0600 0000 0000 0200 0100 0700 0800 0100
    0900 0000 1d00 0100 0100 0000 052a b700
    01b1 0000 0001 000a 0000 0006 0001 0000
    0001 0009 000b 000c 0001 0009 0000 0025
    0002 0001 0000 0009 b200 0212 03b6 0004
    b100 0000 0100 0a00 0000 0a00 0200 0000
    0300 0800 0400 0100 0d00 0000 0200 0e
    
  • 魔数
    四个字节 cafe babe

  • 版本号
    四个字节0000(副版本号) 0034(52主版本号)

    jdk版本  主版本号
    jdk 1.4 	48
    jdk 1.5 	49
    jdk 1.6 	50
    jdk 1.7 	51
    jdk 1.8 	520034)
    jdk 1.9 	53
    
  • 常量池

    001d29) 开始两个字节表示常量池大小
    紧接着都是常量池数据,具体可以参考下面这张表看,一共14种常量类型,每种常量结构还一样,
    但是第一个字节都表示tag,也就是常量类型,只是后面具体数据类型就不一样了
    比如紧接着:
    0a (10) 第10种常量,他的常量类型结构如下:
    {
          
          
     u1 tag; //常量类型
     u2 class_index;//类名称字符串在常量中索引,方法所在类的类信息
     u2 name_and_type_index;//指向CONSTanT_NameAndType_info类型常量的索引
    }
    //类名称索引值 00 06(常量池下标为6的常量)
    //CONSTanT_NameAndType_info类型常量的索引 00 0f(常量池下标为15的常量)
    //下面使用了javap -v 直接分析的常量池结果,确实是29个
    //00 06 第六个是 // java/lang/Object 也就是说这个方法在Oject中
    //00 0f 第15个是 //  "<init>":()V 表示方法名称<init>,参数(),返回值类型V
    说明:这里只是指导查看原理,其他自己去查资料,下一个常量池的常量类型为09这样看下去
    

    在这里插入图片描述
    javap -v Hello 查看在这里插入图片描述

  • Access flags(类的修饰符)
    在这里插入图片描述
    画红线就是常量池结束的地方,接下来两个字节就是表示类修饰符的 为 00 21(0000 0000 0010 0001),具体
    对照如下看
    在这里插入图片描述
    在这里插入图片描述
    结果为 acc_public | acc_super

  • this_class,super_name,interfaces(类,父类,接口的常量池索引,分别两个字节,按照上面图看)
    00 05(常量池中#5) 00 06(常量池中#6) 00 00
    常量池中#5为Hello 常量池中#6为Object类

猜你喜欢

转载自blog.csdn.net/weixin_38312719/article/details/106368202