Reputation: 5
public enum Fruit {
ORANGE(1), APPLE(2);
private final int i;
Fruit(int i){
this.i=i;
}
}
//
// 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
}
Why is there a mismatch between show bytecode and class file?
I looked into how to proceed with the Decompile process in intellij, but I couldn't find any official reference.
I believe the result of show bytecode is not the raw ByteCode. This is because the raw bytecode is not human-readable.
So, as a result of Show bytecode, the decompiled version of the class file is both in processed form. Why is there a discrepancy between the two?
(I also heard that class files are composed of bytecode)
Is this a problem caused by a difference between the decompilation process and the show bytecode process, and the latter being more resilient of the two? (guess)
Upvotes: -2
Views: 175
Reputation: 719299
Why is there a discrepancy between the two?
If you are asking why there is a discrepancy between ".class file" and "show bytecode result", that is because they are showing different things:
If you are asking why "original .java file" and ".class file" are different, they are (once again) showing different things.
In this case, the decompiled code is different to the original. It looks like the decompiler was not able to reconstruct the constructor for the enum
and its private int
variable. That is a limitation of the decompiler that Intellij is using. I imagine that that limitation could be fixed3. However decompilers limitations are inherent, and can't be fixed. These include:
1 - This is not as useful as you might think. The "problem" is that bytecodes are (deliberately) not optimized. Instead the JIT compiler will (eventually) compile + optimize the bytecodes to native code. Often the transformations performed by the JIT compiler are pretty radical; e.g. inlining methods, optimizing away unnecessary loops, and so on. This means that supposed performance insights you might get from reading the bytecodes are (at best) unreliable.
2 - It may not be functionally identical to the original code. Indeed, it may not even be valid Java source code. There are various reasons for this.
3 - ... if someone is willing to put in the work. Indeed, it is possible that the problem is already addressed in a (hypothetical) more recent version of the decompiler.
Upvotes: 2
Reputation: 1361
What you're referring to as the .class
file is actually, as the FernFlower comment explains, recreated source code. The .class
file was run through a decompiler that attempts to convert the bytecode back into its original source code.
The "show bytecode result" code that you pasted is just a readable representation of the contents of the file
Upvotes: 0