作业帮 > JAVA > 教育资讯

Java培训课程:Javaclass文件结构

来源:学生作业帮助网 编辑:作业帮 时间:2024/05/10 03:18:37 JAVA
Java培训课程:Javaclass文件结构
Java培训课程:Javaclass文件结构JAVA
【网络综合-Java培训课程:Javaclass文件结构】:

 现在已经预定义的属性有:

  1. SourceFile : attribute_info被替代为:

  SourceFile_attribute {

  u2 attribute_name_index;

  u4 attribute_length;

  u2 sourcefile_index; //指向constant_pool中的一个CONSTANT_Utf8_info 结构。

  }

  2. ConstantValue : attribute_info被替代为:

  ConstantValue_attribute {

  u2 attribute_name_index;

  u4 attribute_length; //必须为2

  u2 constantvalue_index;

  }

  对于constantvalue_index意义如下:

  long CONSTANT_Long

  float CONSTANT_Float

  double CONSTANT_Double

  int, short, char, byte, boolean CONSTANT_Integer

  String CONSTANT_String

  ConstantValue用于field_info 中,用于描述一个static常量,

  且此时field_info的access_flags应为ACC_STATIC

  3. Code : attribute_info被替代为:

  Code_attribute {

  u2 attribute_name_index;

  u4 attribute_length;

  u2 max_stack; //执行此函数时可用的栈的最大深度

  u2 max_locals; //执行此函数可用到的最大本地变量数目,包括参数。

  // 注意:一个long/double相当于2个变量数目.

  u4 code_length; //本函数用到的代码长度。

  u1 code[code_length]; //实现本函数的真正字节码

  u2 exception_table_length;

  { u2 start_pc;

  u2 end_pc; //捕获违例时执行代码数组中的[start_pc, end_pc)部分

  u2 handler_pc; //现在还不大明白他是干嘛的!!

  u2 catch_type; //指向constant_pool的索引,对应CONSTANT_Class_info

  }exception_table[exception_table_length];

  u2 attributes_count;

  attribute_info attributes[attributes_count];

  }

  CONSTANT_Class_info {

  u1 tag; //必须为CONSTANT_Class (7)

  u2 name_index; //不用我再说了吧?

  }

  Code属性用于method_info结构中。

  4. Exceptions : attribute_info被替代为:

  Exceptions_attribute {

  u2 attribute_name_index;

  u4 attribute_length;

  u2 number_of_exceptions;

  u2 exception_index_table[number_of_exceptions];

  }

  5. InnerClasses : attribute_info被替代为:

  InnerClasses_attribute {

  u2 attribute_name_index;

  u4 attribute_length;

  u2 number_of_classes;

  { u2 inner_class_info_index;

  u2 outer_class_info_index;

  u2 inner_name_index;

  u2 inner_class_access_flags;

  } classes[number_of_classes];

  }

  6. Synthetic : attribute_info被替代为:

  Synthetic_attribute {

  u2 attribute_name_index; //不用废话了吧?

  u4 attribute_length; //必须为0

  }

  Synthetic用在 field_info、 method_info 中,

  一个没有出现在源程序中的变量必须使用Synthetic标记。

  7. LineNumberTable : attribute_info被替代为:

  LineNumberTable_attribute {

  u2 attribute_name_index;

  u4 attribute_length;

  u2 line_number_table_length;

  { u2 start_pc; //代码数组中的开始处

  u2 line_number; //源文件中的行号(对于每一非空行都有这么一项)

  } line_number_table[line_number_table_length];

  }

  LineNumberTable用于Code属性中,通常用于调试。

  8. LocalVariableTable : attribute_info被替代为:

  LocalVariableTable_attribute {

  u2 attribute_name_index;

  u4 attribute_length;

  u2 local_variable_table_length;

  { u2 start_pc;

  u2 length; //当解释到代码数组的[start_pc,start_pc+length]

  //时变量必须被赋值??

  u2 name_index;

  u2 descriptor_index;

  u2 index; //到本地变量数组的一个索引

  } local_variable_table[local_variable_table_length];

  }

  9. Deprecated : attribute_info被替代为:

  Deprecated_attribute {

  u2 attribute_name_index;

  u4 attribute_length; //必须为0

  }

  当然你也可以定义自己的属性,但要你自己的编译器和虚拟机实现。JVM将忽略自己不认可的属性。

  来实践一下吧!

  编写一个最简单的程序:

  class Test

  {

  public static void main(String[] args)

  {

  System.out.println("Hello World!");

  }

  }

  c:\work>javac Test.java

  c:\work>filedump Test.class

  File Dump V0.3 Beta by cloud (safesuite@363).

  01:00 ca fe ba be 00 03 00 2d 00 1d 0a 00 06 00 0f 09 .......-........

  01:01 00 10 00 11 08 00 12 0a 00 13 00 14 07 00 15 07 ................

  01:02 00 16 01 00 06 3c 69 6e 69 74 3e 01 00 03 28 29 ........()

  01:03 56 01 00 04 43 6f 64 65 01 00 0f 4c 69 6e 65 4e V...Code...LineN

  01:04 75 6d 62 65 72 54 61 62 6c 65 01 00 04 6d 61 69 umberTable...mai

  01:05 6e 01 00 16 28 5b 4c 6a 61 76 61 2f 6c 61 6e 67 n...([Ljava/lang

  01:06 2f 53 74 72 69 6e 67 3b 29 56 01 00 0a 53 6f 75 /String;)V...Sou

  01:07 72 63 65 46 69 6c 65 01 00 09 54 65 73 74 2e 6a rceFile...Test.j

  >d

 02:00 61 76 61 0c 00 07 00 08 07 00 17 0c 00 18 00 19 ava.............

  02:01 01 00 0c 48 65 6c 6c 6f 20 57 6f 72 6c 64 21 07 ...Hello World!.

  02:02 00 1a 0c 00 1b 00 1c 01 00 04 54 65 73 74 01 00 ..........Test..

  02:03 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 .java/lang/Objec

  02:04 74 01 00 10 6a 61 76 61 2f 6c 61 6e 67 2f 53 79 t...java/lang/Sy

  02:05 73 74 65 6d 01 00 03 6f 75 74 01 00 15 4c 6a 61 stem...out...Lja

  02:06 76 61 2f 69 6f 2f 50 72 69 6e 74 53 74 72 65 61 va/io/PrintStrea

  02:07 6d 3b 01 00 13 6a 61 76 61 2f 69 6f 2f 50 72 69 m;...java/io/Pri

  >d

  03:00 6e 74 53 74 72 65 61 6d 01 00 07 70 72 69 6e 74 ntStream...print

  03:01 6c 6e 01 00 15 28 4c 6a 61 76 61 2f 6c 61 6e 67 ln...(Ljava/lang

  03:02 2f 53 74 72 69 6e 67 3b 29 56 00 20 00 05 00 06 /String;)V. ....

  03:03 00 00 00 00 00 02 00 00 00 07 00 08 00 01 00 09 ................

  03:04 00 00 00 1d 00 01 00 01 00 00 00 05 2a b7 00 01 ............*...

  03:05 b1 00 00 00 01 00 0a 00 00 00 06 00 01 00 00 00 ................

  03:06 01 00 09 00 0b 00 0c 00 01 00 09 00 00 00 25 00 ..............%.

  03:07 02 00 01 00 00 00 09 b2 00 02 12 03 b6 00 04 b1 ................

  >d

  04:00 00 00 00 01 00 0a 00 00 00 0a 00 02 00 00 00 05 ................

  04:01 00 08 00 06 00 01 00 0d 00 00 00 02 00 0e ..............

  >

  解读一下:

  ca fe ba be magic

  00 03 00 2d 次主版本号,换算一下: 45.3 (注意,不是高字节在前,别犯职业病!)

  00 1d constant_pool元素个数加一 : 29 那么constant_pool就是[1-28]

  constant_pool: 1-28

  1. 0a 00 06 00 0f

  0x0a :CONSTANT_InterfaceMethodref 0x06 :class index 0x0f :name-type-index

  2. 09 00 10 00 11

  0x09 : CONSTANT_Fieldref 0x10: . . . 0x11 : . . . .

  3. 08 00 12 0x08 : CONSTANT_String 0x12 : string_index

  4. 0a 00 13 00 14 0x0a同于1.

  5. 07 00 15 0x07 : CONSTANT_Class 0x15 : name_index

  6. 07 00 16

  7. 01 00 06 3c 69 6e 69 74 3e 01 ...

  0x01 CONSTANT_Utf8 0x06 : string length "" : 构造函数

  8. 01 00 03 28 29 56 ...()V 函数,无参数

  0x01 . . . . . . 0x03 : . . . . "()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 04 6d 61 69 6e ...main

  12. 01 00 16 28 5b 4c 6a 61 76 61 2f 6c 61 6e 67 2f 53 74 72 69 6e 67 3b 29 56

  ...([Ljava/lang/String;)

  V 函数,参数为String[]类型

  13. 01 00 0a 53 6f 75 72 63 65 46 69 6c 65 ...SourceFile

  14. 01 00 09 54 65 73 74 2e 6a 61 76 61 ...Test.java

  15. 0c 00 07 00 08 0x0c:CONSTANT_NameAndType 07 : name-index 08:name-type-index

  16. 07 00 17

  17. 0c 00 18 00 19

  18. 01 00 0c 48 65 6c 6c 6f 20 57 6f 72 6c 64 21 ...Hello World!

  19. 07 00 1a

  20. 0c 00 1b 00 1c

 21. 01 00 04 54 65 73 74 ...Test

  22. 01 00 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 ...java/lang/Object

  23. 01 00 10 6a 61 76 61 2f 6c 61 6e 67 2f 53 79 73 74 65 6d ...java/lang/System

  24. 01 00 03 6f 75 74 ...out

  25. 01 00 15 4c 6a 61 76 61 2f 69 6f 2f 50 72 69 6e 74 53 74 72 65 61 6d 3b

  ...Ljava/io/PrintStream;

  26. 01 00 13 6a 61 76 61 2f 69 6f 2f 50 72 69 6e 74 53 74 72 65 61 6d...java/io/PrintStream

  27. 01 00 07 70 72 69 6e 74 6c 6e ...println

  28. 01 00 15 28 4c 6a 61 76 61 2f 6c 61 6e 67 2f 53 74 72 69 6e 67 3b 29 56

  ...(Ljava/lang/String;)V

  00 20 access_flags

  00 05 this_class

  00 06 super_class

  00 00 interfaces_count

  00 00 fields_count

  00 02 methods_count

  methods[2]:

  method_info {

  u2 access_flags;

  u2 name_index;

  u2 descriptor_index;

  u2 attributes_count;

  attribute_info attributes[attributes_count];

  }

  0. 00 00 access_flags;

  00 07 name_index; 看看constant_pool的第7项: 表明当前描述构造函数

  00 08 descriptor_index;

  00 01 attributes_count;

  00 09 attribute_name_index 0x09 看看constant_pool的第9项,简单明了Code !!

  00 00 00 1d attribute_length = 29

  00 01 max_stack

  00 01 max_locals

  00 00 00 05 code_length

  2a b7 00 01 b1 JVM定义的操作码代码段数组

  00 00 exception_table_length

  00 01 attributes_count 一个,接下来是attribute_info结构

  00 0a attribute_name_index 看看constant_pool的第10项: LineNumberTable(显然调试用)

  00 00 00 06 attribute_length

  00 01 line_number_table_length

  00 00 start_pc

  00 01 line_number

  1. 00 09 access_flags PUBLIC & STATIC

  00 0b name_index; 表明当前描述main函数

  00 0c descriptor_index; ...([Ljava/lang/String;)V

  00 01 attributes_count;

  00 09 attribute_name_index Code

  00 00 00 25 attribute_length = 37

  00 02 max_stack

  00 01 max_locals

  00 00 00 09 code_length

  b2 00 02 12 03 b6 00 04 b1 代码数组 codeArray1[0-8]

  00 00 exception_table_length

  00 01 attributes_count 接下来是attribute_info结构

  00 0a attribute_name_index LineNumberTable

  00 00 00 0a attribute_length

  00 02 line_number_table_length

  00 00 start_pc

  00 05 line_number

  00 08 start_pc : codeArray1[8] = 0xb1 --> return

  00 06 line_number 第6行源程序为 }

  00 01 attributes_count

  00 0d attribute_name_index 属性为SourceFile

  00 00 00 02 attribute_length

  00 0e sourcefile_index constant_pool[0x0e] --- > "Test.java"

  接下来我们看看main()函数对应的代码:

  b2 00 02 12 03 b6 00 04 b1

  0xb2 0x00 0x02 : getstatic #2

  看看constant_pool[0x02] :09 00 10 00 11

  0x09 : CONSTANT_Fieldref 0x10: class index 0x11 :name-type-index

  constant_pool[0x10]: --> constant_pool[0x17] : java/lang/System

  constant_pool[0x11]: 0x18 : class index 0x19 :name-type-index

  constant_pool[0x18] : out

  constant_pool[0x19] : Ljava/io/PrintStream

  即 System.out 为 java.io.PrintStream 类型

  0x12 0x03 : ldc #3

  看看 constant_pool[3] : 08 00 12 0x08 : CONSTANT_String 0x12 : string_index

  指向一个字符串 constant_pool[0x12]: "Hello World!"

  故该指令加载了字符串索引到本地栈

  0xb6 0x00 0x04: invokevirtual #4

  ------->到constant_pool查查 0x13 :class 0x14 :name-type

  看看constant_pool[0x13]:java/io/PrintStream

  constant_pool[20] :--> 00 1b 00 1c

  constant_pool[0x1b]:println

  . . . . :(Ljava/lang/String;)V

  故该指令调用了 java.io.PrintStream.println(java.lang.String)

  而参数则为 ldc #3 加载的 "Hello World!"

  0xb1 : return

JAVA