美文网首页
java Class文件结构

java Class文件结构

作者: Ace_b90f | 来源:发表于2020-06-11 09:50 被阅读0次

    该文章是再次读《深入理解java虚拟机》6.3章class类文件的结构的学习记录

    使用javac -target 1.6将下列代码编译为字节码文件

    package org.fenixsoft.clazz;
    
    public class TestVersion {
        private int m;
        public int inc(){
            return m + 1;
        }
    }
    

    字节码文件可以通过vscode+hexdump插件来查看,内容如下

      Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F   
    00000000: CA FE BA BE 00 00 00 32 00 13 0A 00 04 00 0F 09    J~:>...2........
    00000010: 00 03 00 10 07 00 11 07 00 12 01 00 01 6D 01 00    .............m..
    00000020: 01 49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29    .I...<init>...()
    00000030: 56 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E    V...Code...LineN
    00000040: 75 6D 62 65 72 54 61 62 6C 65 01 00 03 69 6E 63    umberTable...inc
    00000050: 01 00 03 28 29 49 01 00 0A 53 6F 75 72 63 65 46    ...()I...SourceF
    00000060: 69 6C 65 01 00 10 54 65 73 74 56 65 72 73 69 6F    ile...TestVersio
    00000070: 6E 2E 6A 61 76 61 0C 00 07 00 08 0C 00 05 00 06    n.java..........
    00000080: 01 00 1F 6F 72 67 2F 66 65 6E 69 78 73 6F 66 74    ...org/fenixsoft
    00000090: 2F 63 6C 61 7A 7A 2F 54 65 73 74 56 65 72 73 69    /clazz/TestVersi
    000000a0: 6F 6E 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F    on...java/lang/O
    000000b0: 62 6A 65 63 74 00 21 00 03 00 04 00 00 00 01 00    bject.!.........
    000000c0: 02 00 05 00 06 00 00 00 02 00 01 00 07 00 08 00    ................
    000000d0: 01 00 09 00 00 00 1D 00 01 00 01 00 00 00 05 2A    ...............*
    000000e0: B7 00 01 B1 00 00 00 01 00 0A 00 00 00 06 00 01    7..1............
    000000f0: 00 00 00 03 00 01 00 0B 00 0C 00 01 00 09 00 00    ................
    00000100: 00 1F 00 02 00 01 00 00 00 07 2A B4 00 02 04 60    ..........*4...`
    00000110: AC 00 00 00 01 00 0A 00 00 00 06 00 01 00 00 00    ,...............
    00000120: 06 00 01 00 0D 00 00 00 02 00 0E                   ...........
    

    根据书中所写,Class文件格式如下

    类型 名称 数量
    u4 magic 1
    u2 minor_version 1
    u2 major_version 1
    u2 constant_poll_count 1
    cp_info constant_poll constant_poll_count
    u2 access_flags 1
    u2 this_class 1
    u2 super_class 1
    u2 interfaces_count 1
    u2 interfaces interfaces_count
    u2 fields_count 1
    field_info fields fields_count
    u2 methods_count 1
    method_info methods methods_count
    u2 attributes_count 1
    attribute_info attributes attributes_count

    需要注意的是method_info和field_info中都可能有attribute_info,而且类文件的结尾也是attribute_info的集合。

    按照上面Class文件结构可以将上面的字节文件分为下面结构

    CA FE BA BE       // magic
    00 00 00 32       // version
    00 13             // constant_pool_count
    // 常量池共19-1个常量,常量计数从1而不是从0开始
    1   0A 00 04 00 0F     // CONSTANT_Methodref_info  tag u1  index u2  index u2
    2   09 00 03 00 10     // CONSTANT_Fieldref_info   tag u1  index u2  index u2
    3   07 00 11
    4   07 00 12           // CONSTANT_Class_info      tag u1  index u2
    5   01 00 01 6D        // CONSTANT_Utf8_info       tag u1  length u2  bytes u1
    6   01 00 01 49       // CONSTANT_Utf8_info       tag u1  length u2  bytes u1
    7   01 00 06 3C 69 6E 69 74 3E         // 对应字符串为<init>
    8   01 00 03 28 29 56                  // 对应字符串()V
    9   01 00 04 43 6F 64 65               // 对应字符串为Code  
    10  01 00 0F 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65    // 对应字符串为LineNumberTable
    11  01 00 03 69 6E 63                  // 对应字符串为inc
    12  01 00 03 28 29 49                  // 对应字符串为()I
    13  01 00 0A 53 6F 75 72 63 65 46 69 6C 65                   // 对应字符串为SourceFile
    14  01 00 10 54 65 73 74 56 65 72 73 69 6F 6E 2E 6A 61 76 61  // 对应字符串为TestVersion.java
    15  0C 00 07 00 08    // CONSTANT_NameAndType_info   tag u1  index u2  index u2
    16  0C 00 05 00 06
    17  01 00 1F 6F 72 67 2F 66 65 6E 69 78 73 6F 66 74 2F 63 6C 61 7A 7A 2F 54 65 73 74 56 65 72 73 69 6F 6E    // 对应字符串为 类的全限定名,即org.fenixsoft.clazz.TestVersion
    18  01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74                                                 // 对应字符串为 Object的类名,即java.lang.Object
    // 常量池结束
    00 21       // access_flags    八个标志位来识别这个类的访问信息,  0021 = 0020 + 0001  ACC_SUPPER 和 ACC_PUBLIC
    00 03       // this_class
    00 04       // super_class
    00 00       // interface_count
                // interafces 因为上面为0因此这里不存在
    00 01       // fields_count
    00 02 00 05 00 06 00 00  // fields,因为后两位表示attributes_count为0,所以不存在attributes
    00 02                    // methods_count
                             // 一共两个方法
    00 01 00 07 00 08 00 01 00 09 00 00 00 1D 00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 01 00 0A 00 00 00 06 00 01 00 00 00 03 // 该方法对应的<init>方法
    00 01 00 0B 00 0C 00 01 00 09 00 00 00 1F 00 02 00 01 00 00 00 07 2A B4 00 02 04 60 AC 00 00 00 01 00 0A 00 00 00 06 00 01 00 00 00 06 // 该方法对应我们写的inc方法。这两个方法都对应了一个LineNumberTable的属性,该属性包含了该方法在Class文件中的行号
    00 01 // attributes_count
    00 0D 00 00 00 02 00 0E // SouceFile属性
    

    相关文章

      网友评论

          本文标题:java Class文件结构

          本文链接:https://www.haomeiwen.com/subject/xmvvtktx.html