转载

Java class 文件简介

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

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

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

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

class文件的基本类型

u11byte 无符号类型

u22byte无符号类型

u44byte 无符号类型

u88byte无符号类型

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

以下是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() {

}

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

Java class 文件简介

以下是使用 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"

简单版本:

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 文件内容项

Java class 文件简介

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

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

constant_pool_count / constant_pool :常量池

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

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

Java class 文件简介

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

Java class 文件简介

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

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

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

XXX_count :就是对应的数量。

Linux公社的RSS地址 : https://www.linuxidc.com/rssFeed.aspx

本文永久更新链接地址: https://www.linuxidc.com/Linux/2019-07/159587.htm

原文  https://www.linuxidc.com/Linux/2019-07/159587.htm
正文到此结束
Loading...