变量在 .class 文件中为什么显示为 var?

huangapple go评论64阅读模式
英文:

Why variable in .class files appear as var?

问题

Decompiled Code (.class文件) 中的变量名称 var0 是因为Java编译器会对方法参数进行重命名以确保在字节码中没有重复的名称。这是编译器优化的一部分。

英文:

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);
        }

    }
}

答案1

得分: 8

在 JVM 级别,类方法被存储为 method_info 结构实例。

>
> method_info {
> u2 access_flags;
> u2 name_index;
> u2 descriptor_index;
> u2 attributes_count;
> attribute_info attributes[attributes_count];
> }
>

  • access_flags 以位标志形式存储修饰符,如 publicfinal
  • name_index 存储方法的名称。
  • descriptor_index 存储 方法描述符,其中包括返回类型和所有参数类型。
  • attributes_countattributes 是运行时可用的属性,如在方法上声明的 @Deprecated

这就是全部。其他的都消失了。.class 文件不知道你函数参数的名称,因为一旦它成为 .class 文件,名称就消失了。反编译器正在重构你的方法,因此它为 JVM 指令中没有名称的变量使用占位符名称。

英文:

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.

huangapple
  • 本文由 发表于 2023年5月18日 04:46:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/76276089.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定