这段代码如何使用保留关键字作为字段名称?

How can this code use reserved keywords as field names?

我在尝试对服务器应用程序启动进行故障排除时,在遗留 java 字节码 中发现了以下结构。 我的 IDE 反编译了一些第三方库,我很好奇这是怎么回事 - 以前从未见过关键字可以用作字节码中的字段名称

Bytecode version is 48.0 (Java 1.4).

public final class f implements UserContext{

private final String try;
private final UserInfo do;

// a lot of code here 

public UserInfo getUserInfo(){
    return this.do;
}

public String getViewName(){
    return this.try;
}

}

Seems like the library was compiled using some obfuscation features, but how can it be on JVM level? Is it permissible without special flags on JVM startup?

UPDATEUserInfo 字段的正确 getter 名称是 getUserInfo——很抱歉让每个人都对方法的命名不明确感到困惑return 值不同,这是一个复制粘贴问题,因为代码位于远程计算机上 w/o 直接访问该站点。

您不能将关键字用作变量名,请参阅 Java 语言规范中的 chapter 3.9

反编译器给了你 bad/buggy 代码。

Java 虚拟机规范(负责定义字节码的外观)no constraints related to keywords on the names of things.

这些约束只存在 on the Java Language level。您使用的字节码不会反编译为有效的 Java,因为它使用的名称在 Java 语言中无效,但 对 JVM 有效。

类似的逻辑适用于仅在 return 类型上不同的两个 getViewName 方法:JVM 规范在字节码中允许(并且工作得很好),但是 Java 语言规范禁止它。

像这样的字节码最常见的原因是 Java 代码被编译为字节码,然后 obfuscated

另一个可能的原因是代码最初不是通过编译Java代码产生的,而是另一种针对JVM的语言。在这种情况下,这是不太可能的,因为没有人会在应该保存视图名称时将变量命名为 do

我几乎认为代码被混淆了,但你也会在方法名称中看到它。有时混淆器会做一些语言不允许的事情,所以当你反编译它们时,你不能重新编译源代码。只有 Java 语法不允许 dotry 作为变量名,JVM(以及 JVM 上 运行 的其他语言)不关心它。

这要么是故意混淆,要么不是从 Java 类.

编译而来

这可能是某种形式的混淆。

字符串 try 可能是 trу。它们实际上是不同的。剪切并粘贴第一个,它将被视为保留关键字 try。剪切并粘贴第二个,它将是一个有效的字段名称。第二种情况下的 y 不是正常的 y。这是一个不同的 unicode 字符。