gpt4 book ai didi

java - 为什么 JVM 允许我们在字节码中命名一个以数字开头的函数?

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:46:25 25 4
gpt4 key购买 nike

Java 语言规范,Java SE 7 版 (§3.8) 定义了标识符

An identifier is an unlimited-length sequence of Java letters and Java digits, the
first of which must be a Java letter.

据我所知,既然方法名是一个标识符,在java中应该不可能以数字开头来命名方法,javac遵守这个规则。

那么,为什么 Java 虚拟机似乎不遵守此规则,允许我们在字节码中命名以数字开头的函数?


这个简单的代码片段将实际打印 f99() 方法名称及其参数值。

public class Test {
public static void main(String[] args) {
Test t = new Test();
System.out.println(t.f99(100));
}

public int f99(int i){
System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName());
return i;
}
}

编译和执行:

$ javac Test.java
$ java Test

输出:

f99
100

可以在编译后反汇编代码,并将所有 f99 重命名为 99(借助 reJ 等工具)。

$ java Test

输出:

99
100

那么,方法的名称实际上是“99”吗?

最佳答案

Java 语言规范限制了有效方法名称中的字符,以帮助明确解析 Java 语言。

JVM 旨在支持 Java 以外的语言。因此,限制不应该相同;除非我们想强制所有非 Java 语言具有相同的限制。为 JVM 选择的限制是允许明确解析方法签名的最小集合,这是一种出现在 JVM 规范而非 JLS 中的格式。

取自JVM Spec

a name must not contain any of the ASCII characters . ; [ / < > :

也就是说,下面是一个有效的JVM签名[Lcom/foo/Bar; , 它的特殊字符已从方法名称中排除。

<>进一步保留以将特殊的 JVM 方法与应用程序方法分开,特别是 <init><clinit> , 这两个都是 JLS 不允许的方法名称。

关于java - 为什么 JVM 允许我们在字节码中命名一个以数字开头的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26791204/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com