为什么显示字节码和类文件不匹配?

问题描述 投票:0回答:1

原始.java文件

public enum Fruit {
    ORANGE(1), APPLE(2);
    private final int i;
    Fruit(int i){
        this.i=i;
    }
}

.class 文件

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

public enum Fruit {
    ORANGE,
    APPLE;

    private Fruit() {
    }
}

显示字节码结果

// class version 61.0 (61)
// access flags 0x4031
// signature Ljava/lang/Enum<LFruit;>;
// declaration: Fruit extends java.lang.Enum<Fruit>
public final enum Fruit extends java/lang/Enum {

  // compiled from: Fruit.java

  // access flags 0x4019
  public final static enum LFruit; ORANGE

  // access flags 0x4019
  public final static enum LFruit; APPLE

  // access flags 0x12
  private final I i

  // access flags 0x101A
  private final static synthetic [LFruit; $VALUES

  // access flags 0x9
  public static values()[LFruit;
   L0
    LINENUMBER 1 L0
    GETSTATIC Fruit.$VALUES : [LFruit;
    INVOKEVIRTUAL [LFruit;.clone ()Ljava/lang/Object;
    CHECKCAST [LFruit;
    ARETURN
    MAXSTACK = 1
    MAXLOCALS = 0

  // access flags 0x9
  public static valueOf(Ljava/lang/String;)LFruit;
   L0
    LINENUMBER 1 L0
    LDC LFruit;.class
    ALOAD 0
    INVOKESTATIC java/lang/Enum.valueOf (Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
    CHECKCAST Fruit
    ARETURN
   L1
    LOCALVARIABLE name Ljava/lang/String; L0 L1 0
    MAXSTACK = 2
    MAXLOCALS = 1

  // access flags 0x2
  // signature (I)V
  // declaration: void <init>(int)
  private <init>(Ljava/lang/String;II)V
   L0
    LINENUMBER 4 L0
    ALOAD 0
    ALOAD 1
    ILOAD 2
    INVOKESPECIAL java/lang/Enum.<init> (Ljava/lang/String;I)V
   L1
    LINENUMBER 5 L1
    ALOAD 0
    ILOAD 3
    PUTFIELD Fruit.i : I
   L2
    LINENUMBER 6 L2
    RETURN
   L3
    LOCALVARIABLE this LFruit; L0 L3 0
    LOCALVARIABLE i I L0 L3 3
    MAXSTACK = 3
    MAXLOCALS = 4

  // access flags 0x100A
  private static synthetic $values()[LFruit;
   L0
    LINENUMBER 1 L0
    ICONST_2
    ANEWARRAY Fruit
    DUP
    ICONST_0
    GETSTATIC Fruit.ORANGE : LFruit;
    AASTORE
    DUP
    ICONST_1
    GETSTATIC Fruit.APPLE : LFruit;
    AASTORE
    ARETURN
    MAXSTACK = 4
    MAXLOCALS = 0

  // access flags 0x8
  static <clinit>()V
   L0
    LINENUMBER 2 L0
    NEW Fruit
    DUP
    LDC "ORANGE"
    ICONST_0
    ICONST_1
    INVOKESPECIAL Fruit.<init> (Ljava/lang/String;II)V
    PUTSTATIC Fruit.ORANGE : LFruit;
    NEW Fruit
    DUP
    LDC "APPLE"
    ICONST_1
    ICONST_2
    INVOKESPECIAL Fruit.<init> (Ljava/lang/String;II)V
    PUTSTATIC Fruit.APPLE : LFruit;
   L1
    LINENUMBER 1 L1
    INVOKESTATIC Fruit.$values ()[LFruit;
    PUTSTATIC Fruit.$VALUES : [LFruit;
    RETURN
    MAXSTACK = 5
    MAXLOCALS = 0
}

为什么显示字节码和类文件不匹配?

我研究了如何在intellij中进行反编译过程,但找不到任何官方参考。

我相信显示字节码的结果不是原始字节码。这是因为原始字节码不是人类可读的。

因此,作为显示字节码的结果,类文件的反编译版本都是经过处理的形式。为什么两者有差异?

(我还听说class文件是由字节码组成的)

这是由反编译过程和显示字节码过程之间的差异引起的问题,而后者在两者中更具弹性吗? (猜)

java intellij-idea compilation bytecode
1个回答
0
投票

您所指的

.class
文件实际上,正如 FernFlower 评论所解释的那样,是重新创建的源代码。
.class
文件通过反编译器运行,尝试将字节码转换回其原始源代码。结果与您的实际代码略有不同,但它们都编译成相同的结果,因此反编译器不可能知道您是从哪一个开始的。

您粘贴的“显示字节码结果”代码只是文件内容的可读表示

© www.soinside.com 2019 - 2024. All rights reserved.