问题
I found the following construction in legacy java bytecode while trying to troubleshoot server application startup. My IDE decompiled some third party libraries and I'm curious how this can be valid - never saw before keywords can be used as field names in bytecode.
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 : the correct getter name for UserInfo
field is getUserInfo
-- sorry for confusing everyone with ambiguous naming for methods with different return values, it's a copy-paste issue as code is located on a remote machine w/o direct access to the site.
回答1:
The Java Virtual Machine Specification (which is responsible for defining what the bytecode looks like) puts no constraints related to keywords on the names of things.
Those constraints only exist on the Java Language level. The bytecode you used does not decompile into valid Java, because it uses names that are not valid in the Java language, but that are valid to the JVM.
A similar logic applies to the two getViewName
methods that differ only in return type: This is allowed (and works perfectly fine) in bytecode by the JVM spec, but the Java Language specification forbids it.
The most common reason for bytecode like this is Java code that was compiled to bytecode and then obfuscated.
Another possible reason is that the code was not originally produced by compiling Java code, but another language that targets the JVM. This is rather unlikely in this case, since no one would name a variable do
when it's supposed to hold the view name.
回答2:
I'd almost think that the code were obfuscated, but then you would see it in method names as well. Sometimes obfuscators do things that aren't allowed in the language, so when you decompile them you can't recompile the source. It's only the Java syntax that doesn't allow do
or try
as variable names, the JVM (and other languages that run on the JVM) doen't care about it.
Either this was deliberate obfuscation or they were not compiled from Java classes.
回答3:
This could be some form of obfuscation.
The string try
could perhaps be trу
. They are actually different. Cut & paste the first one and it will be treated as the reserved keyword try
. Cut & paste the second one and it will be a valid field name. The y
in the second case is not a normal y
. It's a different unicode character.
回答4:
You can't use keywords as variable names, see chapter 3.9 in the Java Language Specification.
The decompiler gave you bad/buggy code.
来源:https://stackoverflow.com/questions/57867547/how-can-this-code-use-reserved-keywords-as-field-names