字节码分析-字段

源码

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"

详细说明

字段描述符

字节码中使用描述符来表示字段类型:

字段访问标志

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

字段访问指令