这段代码如何使用保留关键字作为字段名称?
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?
UPDATE:UserInfo
字段的正确 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 语法不允许 do
或 try
作为变量名,JVM(以及 JVM 上 运行 的其他语言)不关心它。
这要么是故意混淆,要么不是从 Java 类.
编译而来
这可能是某种形式的混淆。
字符串 try
可能是 trу
。它们实际上是不同的。剪切并粘贴第一个,它将被视为保留关键字 try
。剪切并粘贴第二个,它将是一个有效的字段名称。第二种情况下的 y
不是正常的 y
。这是一个不同的 unicode 字符。
我在尝试对服务器应用程序启动进行故障排除时,在遗留 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?
UPDATE:UserInfo
字段的正确 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 语法不允许 do
或 try
作为变量名,JVM(以及 JVM 上 运行 的其他语言)不关心它。
这要么是故意混淆,要么不是从 Java 类.
编译而来这可能是某种形式的混淆。
字符串 try
可能是 trу
。它们实际上是不同的。剪切并粘贴第一个,它将被视为保留关键字 try
。剪切并粘贴第二个,它将是一个有效的字段名称。第二种情况下的 y
不是正常的 y
。这是一个不同的 unicode 字符。