*.class is a compilation of *.java. Let’s take a look at the file structure of a class using a minimal example
The source code
package sample.asm.readclass;
public class Test {
private String name;
}
Copy the code
decompiling
The Java Virtual Machine Specification Java SE 7 Edition
Cp_info = constant_pool[constant_pool_count-1]; cp_info = constant_pool_count-1; But don’t make the mistake of thinking that all constant pools have the same length, because this is just a way of describing arrays, but it’s not like programming language where you have an array of ints, and every int has the same length.
(1) Magic number: CAFEBABE
Minor_version (2) : 0000
Major_version (3) : 0034
(4) Number of constant pools 000F (decimal: 15)
The number of constant pools is constant_pool_count-1, which is reduced by one because index 0 indicates that data items in class do not reference any constants in the constant pool.
(5) the constant pool
Each constant has a tag of type U1 to indicate the type of the constant. The first constant is of type 0x0A (10)
tag | class_index | name_and_type_index |
---|---|---|
0A | 0003 | 000C |
— | #3(#14 java/lang/Object) | #12(#6#7 ()V) |
(6)u2 access_flags 0021
Represents access information about a Class or interface, such as whether Class represents a Class or interface, whether it is public,static, final, etc. 0 x0021 = 0 x0001 | 0 x0020 means ACC_PUBLIC and ACC_SUPER is true, including ACC_PUBLIC everybody understanding, ACC
_SUPER is the flag that all classes compiled after JDK1.2 carry.
(7)u2 this_class 0002
Said class index value, is used to sample indicates the fully qualified class name/asm/readclass/Test
U2 super_class (8) : 0003
Represents the index value of the parent class of the current class Java /lang/Object
(9)interfaces_count and interfaces[interfaces_count] indicate the number of interfaces and their specific interfaces
(10) fields_count and field_info
fields_count:1 (0001)
field_info:0002 0004 0005 0000
access_flag | name_index | descriptor_index | attribute_count |
---|---|---|---|
0002 | 0004 | 0005 | 0000 |
— | name | Ljava/lang/String; | 0 |
(11) methods_count and method_info:
access_flag | name_index | descriptor_index | attribute_count | attribute_info |
---|---|---|---|---|
0001 | 0006 | 0007 | 0001 | — |
— | <init> | ()V | 1 | — |
And then the constant in attribute_info 0008’s constant pool is Code, which represents the Code attribute of the method, so the Code for the method is stored in the Code attribute in the attribute table of the method table in the Class file. Next, we will analyze the Code attribute. The structure of the Code attribute is as follows
attribute_name_index | attribute_length | max_stack | max_locals | code_length | code[code_length] |
---|---|---|---|---|---|
0008 | 0000001D | 0001 | 0001 | 00000005 | 2AB70001B1 |
exception_table_length | attribute_count | attribute_info |
---|---|---|
0000 | 0001 | — |
LineNumberTable is used to describe the relationship between the Java source line number and the bytecode line number. LineNumberTable is not a required property at runtime. If LineNumberTable is disabled with the -g: None compiler argument, the most important effect is that the stack cannot display the line number of the error when the exception occurs, and the breakpoint cannot be set from the source code when debugging.
attribute_name_index | attribute_length | Byte stream |
---|---|---|
0009 | 00000006 | 0001(has 1 line number table) 0000(bytecode line number 0) 0003(source line number 3) |
Class file properties
Number of attributes: 0001
attribute_name_index | attribute_length | sourcefile_index |
---|---|---|
000A | 00000002 | 000B |
SourceFile | 00000002 | Test.java |