Java源代码与反编译结果不一致

问题描述 投票:0回答:1

在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-8 decompiler
1个回答
0
投票

Java 中的反编译将类文件读回 .java 源文件。 在反编译过程中,由于编译过程中应用的优化和安全性,变量名称经常会丢失。 反编译的主要目的是理解代码的逻辑而不是重新编译它。有时,您甚至可能会遇到所有变量都可以命名为单个变量的情况,不知道为什么,但我认为其中应用了一些安全性,并且很难阅读和理解。

您应该尝试另一个反编译器以更好地理解反编译,尝试

JD-GUI
Intellij Idea
反编译器是最好的,但它仍然可以实现其目的,使无法访问原始源代码的个人能够理解代码的流程。

如果仔细查看反编译代码,您需要理解

b1 = ""
可以
String b1 = String.valueOf(Math.random());
引用不同的变量。因为在同一个作用域中“不可能”有相同的 b1 变量。反编译器不明白这一点,它只是读取,内存地址
b1
中有一个
XXXX
变量,内存地址
YYYY
中有另一个变量。反编译器尝试找到变量名称并给出
b1
,这是不正确的。

而且,不仅是变量,有时循环也可以不同。

希望这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.