0

I was curious about .class files and the code inside and realised that variables in one of the classes that I compiled is named as var0 which is very interesting.

I am wondering if someone could explain why.

Java Code (.java file):

public class StackOverflowExample {
    public static void main(String[] args) {
        loop(50_000);
        System.out.println("Success!");
    }

    public static void loop(int repeats) {
        if (repeats > 0) {
            loop(repeats - 1);
        }
    }
}

Decompiled Code (.class file):

public class StackOverflowExample {
    public StackOverflowExample() {
    }

    public static void main(String[] var0) {
        loop(50000);
        System.out.println("Success!");
    }

    public static void loop(int var0) {
        if (var0 > 0) {
            loop(var0 - 1);
        }

    }
}
Artyom
  • 21
  • 4
  • 3
    Why would it preserve the variable name? – shmosel May 17 '23 at 20:52
  • 6
    Variable names are lost during compilation, they are not needed for the bytecode and hence dropped. The decompiler you used just guessed some names for you. – Zabuzard May 17 '23 at 20:52
  • 3
    This question is related https://stackoverflow.com/questions/5746894/what-does-the-javac-debugging-information-option-gvars-do – Vasily Liaskovsky May 17 '23 at 20:57
  • @shmosel – Because the decompiled code would look nicer? Ok, I could not imagine any other reason … – tquadrat May 17 '23 at 21:43

1 Answers1

8

At the JVM level, a class method is stored as a method_info struct instance.

method_info {
    u2             access_flags;
    u2             name_index;
    u2             descriptor_index;
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}
  • access_flags stores modifiers like public and final as bitflags.
  • name_index stores the name of the method.
  • descriptor_index stores the method descriptor, which is its return type and all parameter types.
  • attributes_count and attributes are the runtime-available attributes such as @Deprecated that are declared on the method.

That's it. Everything else is gone. The .class file doesn't know the name of your function's parameter because that name stopped existing the moment it became a .class file. The decompiler is reconstructing your method, so it's using a placeholder name for variables that don't have names in the JVM instructions.

Silvio Mayolo
  • 62,821
  • 6
  • 74
  • 116
  • 2
    Note that the `attributes` *can* include attributes called `LocalVariableTable` which give information about the names of local variables. But that information is purely informational: it's useful for debugging, but not necessary for execution. Also the code of the method itself is actually [an attribute](https://docs.oracle.com/javase/specs/jvms/se20/html/jvms-4.html#jvms-4.7.3). So attributes are not just annotation-type information, but some fundamentally important parts of the method as well. – Joachim Sauer May 17 '23 at 22:09