zoukankan      html  css  js  c++  java
  • Java class 文件简介

    Java class 文件时对Java程序二进制文件格式的精确定义。

    一个class文件只能包含一个类或接口。

    Java class文件是8位字节的二进制流。

    在Java class文件中,可变长度项的大小和长度位于其实际数据之前。

    class文件的基本类型

      u1  1byte   无符号类型

      u2  2byte  无符号类型

      u4  4byte   无符号类型

      u8  8byte  无符号类型

    =============================================================================================================================

    以下是Java源码文件

    public class ClassTest {
        final static int constantInt=12;
        final static String  constantString="我很好";
        static int variableInt=12;
        static String  variableString="我很好";
        private int variable;
        private String variable2;
    
        public static void main(String[] args) {
            System.out.println("--这是main()方法---");
    
        }
        public void say() {
            System.out.println("这是普通方法");
        }
        public ClassTest(int variable, String variable2) {
            super();
            this.variable = variable;
            this.variable2 = variable2;
        }
        public ClassTest() {
            
        }
    View Code

    以下是使用uedit 编辑器查看的字节码文件

      

    以下是使用 javap -v ClssTest.class  查看的字节码文件内容 

     Last modified 2019-7-24; size 924 bytes
      MD5 checksum be5b20653620d7d2b495a3f99e3fb417
      Compiled from "ClassTest.java"
    public class ClassTest
      minor version: 0
      major version: 52
      flags: ACC_PUBLIC, ACC_SUPER
    Constant pool:
       #1 = Fieldref           #34.#35        // java/lang/System.out:Ljava/io/PrintStream;
       #2 = String             #36            // --这是main()方法---
       #3 = Methodref          #37.#38        // java/io/PrintStream.println:(Ljava/lang/String;)V
       #4 = String             #39            // 这是普通方法
       #5 = Methodref          #12.#40        // java/lang/Object."<init>":()V
       #6 = Fieldref           #11.#41        // ClassTest.variable:I
       #7 = Fieldref           #11.#42        // ClassTest.variable2:Ljava/lang/String;
       #8 = Fieldref           #11.#43        // ClassTest.variableInt:I
       #9 = String             #44            // 我很好
      #10 = Fieldref           #11.#45        // ClassTest.variableString:Ljava/lang/String;
      #11 = Class              #46            // ClassTest
      #12 = Class              #47            // java/lang/Object
      #13 = Utf8               constantInt
      #14 = Utf8               I
      #15 = Utf8               ConstantValue
      #16 = Integer            12
      #17 = Utf8               constantString
      #18 = Utf8               Ljava/lang/String;
      #19 = Utf8               variableInt
      #20 = Utf8               variableString
      #21 = Utf8               variable
      #22 = Utf8               variable2
      #23 = Utf8               main
      #24 = Utf8               ([Ljava/lang/String;)V
      #25 = Utf8               Code
      #26 = Utf8               LineNumberTable
      #27 = Utf8               say
      #28 = Utf8               ()V
      #29 = Utf8               <init>
      #30 = Utf8               (ILjava/lang/String;)V
      #31 = Utf8               <clinit>
      #32 = Utf8               SourceFile
      #33 = Utf8               ClassTest.java
      #34 = Class              #48            // java/lang/System
      #35 = NameAndType        #49:#50        // out:Ljava/io/PrintStream;
      #36 = Utf8               --这是main()方法---
      #37 = Class              #51            // java/io/PrintStream
      #38 = NameAndType        #52:#53        // println:(Ljava/lang/String;)V
      #39 = Utf8               这是普通方法
      #40 = NameAndType        #29:#28        // "<init>":()V
      #41 = NameAndType        #21:#14        // variable:I
      #42 = NameAndType        #22:#18        // variable2:Ljava/lang/String;
      #43 = NameAndType        #19:#14        // variableInt:I
      #44 = Utf8               我很好
      #45 = NameAndType        #20:#18        // variableString:Ljava/lang/String;
      #46 = Utf8               ClassTest
      #47 = Utf8               java/lang/Object
      #48 = Utf8               java/lang/System
      #49 = Utf8               out
      #50 = Utf8               Ljava/io/PrintStream;
      #51 = Utf8               java/io/PrintStream
      #52 = Utf8               println
      #53 = Utf8               (Ljava/lang/String;)V
    {
      static final int constantInt;
        descriptor: I
        flags: ACC_STATIC, ACC_FINAL
        ConstantValue: int 12
    
      static final java.lang.String constantString;
        descriptor: Ljava/lang/String;
        flags: ACC_STATIC, ACC_FINAL
        ConstantValue: String 我很好
    
      static int variableInt;
        descriptor: I
        flags: ACC_STATIC
    
      static java.lang.String variableString;
        descriptor: Ljava/lang/String;
        flags: ACC_STATIC
    
      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     #1                  // Field java/lang/System.out:Ljava/io/PrintStream;
             3: ldc           #2                  // String --这是main()方法---
             5: invokevirtual #3                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
             8: return
          LineNumberTable:
            line 11: 0
            line 13: 8
    
      public void say();
        descriptor: ()V
        flags: ACC_PUBLIC
        Code:
          stack=2, locals=1, args_size=1
             0: getstatic     #1                  // Field java/lang/System.out:Ljava/io/PrintStream;
             3: ldc           #4                  // String 这是普通方法
             5: invokevirtual #3                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
             8: return
          LineNumberTable:
            line 15: 0
            line 16: 8
    
      public ClassTest(int, java.lang.String);
        descriptor: (ILjava/lang/String;)V
        flags: ACC_PUBLIC
        Code:
          stack=2, locals=3, args_size=3
             0: aload_0
             1: invokespecial #5                  // Method java/lang/Object."<init>":()V
             4: aload_0
             5: iload_1
             6: putfield      #6                  // Field variable:I
             9: aload_0
            10: aload_2
            11: putfield      #7                  // Field variable2:Ljava/lang/String;
            14: return
          LineNumberTable:
            line 18: 0
            line 19: 4
            line 20: 9
            line 21: 14
    
      public ClassTest();
        descriptor: ()V
        flags: ACC_PUBLIC
        Code:
          stack=1, locals=1, args_size=1
             0: aload_0
             1: invokespecial #5                  // Method java/lang/Object."<init>":()V
             4: return
          LineNumberTable:
            line 22: 0
            line 24: 4
    
      static {};
        descriptor: ()V
        flags: ACC_STATIC
        Code:
          stack=1, locals=0, args_size=0
             0: bipush        12
             2: putstatic     #8                  // Field variableInt:I
             5: ldc           #9                  // String 我很好
             7: putstatic     #10                 // Field variableString:Ljava/lang/String;
            10: return
          LineNumberTable:
            line 5: 0
            line 6: 5
    }
    SourceFile: "ClassTest.java"
    View Code

    简单版本:

      

     minor version: 0        //---主版本号
      major version: 52        //---次版本号      
      flags: ACC_PUBLIC, ACC_SUPER    //---类访问标识
     //--- 常量池 
    Constant pool:
       #1 = Fieldref           #34.#35        // java/lang/System.out:Ljava/io/PrintStream;
       #2 = String             #36            // --这是main()方法---
       .......
       #52 = Utf8               println
       #53 = Utf8               (Ljava/lang/String;)V
    {
    //--- 字段信息
      static final int constantInt;
        descriptor: I
        flags: ACC_STATIC, ACC_FINAL
        ConstantValue: int 12
    
    
      static int variableInt;
        descriptor: I
        flags: ACC_STATIC
    
    
    //---方法信息
      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     #1                  // Field java/lang/System.out:Ljava/io/PrintStream;
             3: ldc           #2                  // String --这是main()方法---
             5: invokevirtual #3                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
             8: return
          LineNumberTable:
            line 11: 0
            line 13: 8
    
     
      public ClassTest();
        descriptor: ()V
        flags: ACC_PUBLIC
        Code:
          stack=1, locals=1, args_size=1
             0: aload_0
             1: invokespecial #5                  // Method java/lang/Object."<init>":()V
             4: return
          LineNumberTable:
            line 22: 0
            line 24: 4
            
    //-- super()方法
      static {};
        descriptor: ()V
        flags: ACC_STATIC
        Code:
          stack=1, locals=0, args_size=0
             0: bipush        12
             2: putstatic     #8                  // Field variableInt:I
             5: ldc           #9                  // String 我很好
             7: putstatic     #10                 // Field variableString:Ljava/lang/String;
            10: return
          LineNumberTable:
            line 5: 0
            line 6: 5
    }

     class 文件内容项

      

     magic(魔数) : class文件前四位字节,class文件总是以 0xCAFEBABE 开头,作为class文件标识。

    minor_version / major_version  主次版本号,JVM 根据版本号决定如何加载class文件

    constant_pool_count / constant_pool :常量池

      每一个常量池入口都是从一个标识(长度是一个字节)开始。次标识指明该位置常量的类型。

      每一个标志都有一个相对的表,表名就是标志名加上“_info”  即 constant_utf8_info

      

      常量池具体描述 : https://blog.csdn.net/hxcaifly/article/details/82887552

    access_flage : 访问标志,指明class文件定义的是类还是接口,以及类或接口的修饰符。

      

    this_class :就是指向常量池中constant_class_info的索引。

    super_class :也是一个指向常量池的索引。

    interfaces / fields / methods /attribute  :也是指向常量池的索引。

    XXX_count :就是对应的数量。

  • 相关阅读:
    《那些年啊,那些事——一个程序员的奋斗史》——117
    《那些年啊,那些事——一个程序员的奋斗史》——116
    《那些年啊,那些事——一个程序员的奋斗史》——116
    《那些年啊,那些事——一个程序员的奋斗史》——118
    《那些年啊,那些事——一个程序员的奋斗史》——119
    《那些年啊,那些事——一个程序员的奋斗史》——117
    《那些年啊,那些事——一个程序员的奋斗史》——119
    283. Move Zeroes
    26. Remove Duplicates from Sorted Array
    268. Missing Number
  • 原文地址:https://www.cnblogs.com/wdp1990/p/11238028.html
Copyright © 2011-2022 走看看