字节码分析-字段
源码
package java.bytecode;
/**
* 字段示例 - 演示各种类型的字段定义
*/
public class FieldExample {
// 静态字段
public static final int STATIC_FINAL_INT = 100;
private static String staticField = "static";
// 实例字段 - 基本类型
private int intField;
private long longField;
private double doubleField;
private boolean booleanField;
private char charField;
// 实例字段 - 对象类型
private String stringField;
// 实例字段 - 数组
private int[] intArray;
private String[] stringArray;
// final字段
private final String finalField = "final";
public FieldExample() {
this.intField = 0;
}
public int getIntField() {
return intField;
}
public void setIntField(int intField) {
this.intField = intField;
}
}
结构化反解析
Classfile /D:/zcp/github/yggdrasil/java/bytecode/FieldExample.class
Last modified 2025-12-3; size 817 bytes
MD5 checksum 9619999c1c93e1981578b61b3f720148
Compiled from "FieldExample.java"
public class java.bytecode.FieldExample
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #2.#3 // java/lang/Object."<init>":()V
#2 = Class #4 // java/lang/Object
#3 = NameAndType #5.#6 // "<init>":()V
#4 = Utf8 java/lang/Object
#5 = Utf8 <init>
#6 = Utf8 ()V
#7 = String #8 // final
#8 = Utf8 final
#9 = Fieldref #10.#11 // java/bytecode/FieldExample.finalField:Ljava/lang/String;
#10 = Class #12 // java/bytecode/FieldExample
#11 = NameAndType #13:#14 // finalField:Ljava/lang/String;
#12 = Utf8 java/bytecode/FieldExample
#13 = Utf8 finalField
#14 = Utf8 Ljava/lang/String;
#15 = Fieldref #10.#16 // java/bytecode/FieldExample.intField:I
#16 = NameAndType #17:#18 // intField:I
#17 = Utf8 intField
#18 = Utf8 I
#19 = String #20 // static
#20 = Utf8 static
#21 = Fieldref #10.#22 // java/bytecode/FieldExample.staticField:Ljava/lang/String;
#22 = NameAndType #23:#14 // staticField:Ljava/lang/String;
#23 = Utf8 staticField
#24 = Utf8 STATIC_FINAL_INT
#25 = Utf8 ConstantValue
#26 = Integer 100
#27 = Utf8 longField
#28 = Utf8 J
#29 = Utf8 doubleField
#30 = Utf8 D
#31 = Utf8 booleanField
#32 = Utf8 Z
#33 = Utf8 charField
#34 = Utf8 C
#35 = Utf8 stringField
#36 = Utf8 intArray
#37 = Utf8 [I
#38 = Utf8 stringArray
#39 = Utf8 [Ljava/lang/String;
#40 = Utf8 Code
#41 = Utf8 LineNumberTable
#42 = Utf8 getIntField
#43 = Utf8 ()I
#44 = Utf8 setIntField
#45 = Utf8 (I)V
#46 = Utf8 <clinit>
#47 = Utf8 SourceFile
#48 = Utf8 FieldExample.java
{
public static final int STATIC_FINAL_INT;
descriptor: I
flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
ConstantValue: int 100
private static java.lang.String staticField;
descriptor: Ljava/lang/String;
flags: ACC_PRIVATE, ACC_STATIC
private int intField;
descriptor: I
flags: ACC_PRIVATE
private long longField;
descriptor: J
flags: ACC_PRIVATE
private double doubleField;
descriptor: D
flags: ACC_PRIVATE
private boolean booleanField;
descriptor: Z
flags: ACC_PRIVATE
private char charField;
descriptor: C
flags: ACC_PRIVATE
private java.lang.String stringField;
descriptor: Ljava/lang/String;
flags: ACC_PRIVATE
private int[] intArray;
descriptor: [I
flags: ACC_PRIVATE
private java.lang.String[] stringArray;
descriptor: [Ljava/lang/String;
flags: ACC_PRIVATE
private final java.lang.String finalField;
descriptor: Ljava/lang/String;
flags: ACC_PRIVATE, ACC_FINAL
ConstantValue: String final
public java.bytecode.FieldExample();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: ldc #7 // String final
7: putfield #9 // Field finalField:Ljava/lang/String;
10: aload_0
11: iconst_0
12: putfield #15 // Field intField:I
15: return
LineNumberTable:
line 29: 0
line 27: 4
line 30: 10
line 31: 15
public int getIntField();
descriptor: ()I
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: getfield #15 // Field intField:I
4: ireturn
LineNumberTable:
line 34: 0
public void setIntField(int);
descriptor: (I)V
flags: ACC_PUBLIC
Code:
stack=2, locals=2, args_size=2
0: aload_0
1: iload_1
2: putfield #15 // Field intField:I
5: return
LineNumberTable:
line 38: 0
line 39: 5
static {};
descriptor: ()V
flags: ACC_STATIC
Code:
stack=1, locals=0, args_size=0
0: ldc #19 // String static
2: putstatic #21 // Field staticField:Ljava/lang/String;
5: return
LineNumberTable:
line 10: 0
}
SourceFile: "FieldExample.java"
详细说明
字段描述符
字节码中使用描述符来表示字段类型:
I- int类型J- long类型D- double类型Z- boolean类型C- char类型Ljava/lang/String;- String对象类型(L开头,分号结尾)[I- int数组[Ljava/lang/String;- String数组
字段访问标志
ACC_PUBLIC- public访问权限ACC_PRIVATE- private访问权限ACC_STATIC- static静态字段ACC_FINAL- final不可变字段
ConstantValue属性
对于编译时常量(如public static final int STATIC_FINAL_INT = 100和private final String finalField = "final"),编译器会将常量值存储在ConstantValue属性中,而不是在构造方法或静态初始化块中赋值。
静态初始化块
<clinit>方法是类初始化方法,用于初始化静态字段。在本例中,staticField的初始化在<clinit>方法中完成:
static {};
Code:
0: ldc #19 // String static
2: putstatic #21 // Field staticField:Ljava/lang/String;
5: return
字段访问指令
getfield- 获取实例字段值putfield- 设置实例字段值getstatic- 获取静态字段值putstatic- 设置静态字段值