在jdk8中
我的代码是
public void a(){
ArrayList<Object> list = new ArrayList<>();
list.add("1");
list.add("2");
for (int i = 0; i < list.size(); i++) {
String b1 = String.valueOf(Math.random());
String b2 = "";
Object o = new Object[]{list.get(i)};
log.info(b1);
log.info(b2);
}
for (int i = 0; i < list.size(); i++) {
Object o = new Object[]{list.get(i)};
String b1 = String.valueOf(Math.random());
String b2 = "";
log.info(b1);
log.info(b2);
}
}
但是编译结果是(我的反编译结果)
public void a() {
ArrayList<Object> list = new ArrayList();
list.add("1");
list.add("2");
int i;
String b1;
for(i = 0; i < list.size(); ++i) {
String b1 = String.valueOf(Math.random());
b1 = "";
(new Object[1])[0] = list.get(i);
log.info(b1);
log.info(b1);
}
for(i = 0; i < list.size(); ++i) {
(new Object[1])[0] = list.get(i);
b1 = String.valueOf(Math.random());
String b2 = "";
log.info(b1);
log.info(b2);
}
}
其中第一个代码中的参数 b2 更改为 b1
并在idea中调试,结果正确
我想知道为什么会发生这样的事
Java 中的反编译将类文件读回 .java 源文件。 在反编译过程中,由于编译过程中应用的优化和安全性,变量名称经常会丢失。 反编译的主要目的是理解代码的逻辑而不是重新编译它。有时,您甚至可能会遇到所有变量都可以命名为单个变量的情况,不知道为什么,但我认为其中应用了一些安全性,并且很难阅读和理解。
您应该尝试另一个反编译器以更好地理解反编译,尝试
JD-GUI
。 Intellij Idea
反编译器是最好的,但它仍然可以实现其目的,使无法访问原始源代码的个人能够理解代码的流程。
如果仔细查看反编译代码,您需要理解
b1 = ""
可以用String b1 = String.valueOf(Math.random());
引用不同的变量。因为在同一个作用域中“不可能”有相同的 b1 变量。反编译器不明白这一点,它只是读取,内存地址 b1
中有一个 XXXX
变量,内存地址 YYYY
中有另一个变量。反编译器尝试找到变量名称并给出 b1
,这是不正确的。
而且,不仅是变量,有时循环也可以不同。
希望这有帮助。