我的应用中有以下代码:
public static final boolean DEBUG = true;
public static final boolean REL = !DEBUG;
private static final String DEBUG_OR_RELEASE = (REL) ? "RELEASE_VER" : "DEBUG_VER";
我认为Java编译器将从生成的.apk文件中完全消除"DEBUG_VER"
字符串(当通过Proguard导出时)但是当我检查.apk文件时,我看到那里的“DEBUG_VER”字符串。
为什么呢?我错过了什么?我做错了什么?
答案 0 :(得分:3)
编译为java字节码没有进行优化(除了极少数例外)。
许多书籍都说明了“编译”阶段在优化发生时的简化,但这是错误的。当优化真正发生时,是字节码文件由JVM处理。因此,为了清除:在编译字节码以加工本机代码时可能会发生优化,这是由JVM工具完成的。
有时根本没有优化(JVM在解释模式下工作)。有时JIT(Just In Time complier)会进行一些优化。有时,自适应优化器负责优化(不仅可以优化,还可以在执行其他操作时分析代码执行)。
最后,您的文件没有任何问题。这就是Java世界的运作方式。
“但为什么?” - 你可能会问。在字节码中保留这些“无用”信息的原因是因为您永远无法确定可以消除多少代码,因此不同JVM提供的优化仍然可以高效工作。最好的方法是不删除任何信息,让优化者完成他们的工作。
答案 1 :(得分:1)
即使变量设置为true,它仍然在运行。 ?:语句是可执行代码和操作代码的一部分,由于Java没有预编译器,每次编译时都会运行。
Java不会自动推断和简化操作,即使逻辑上每次迭代的操作都相同。
答案 2 :(得分:1)
根据您发布的内容,DEBUG
为真,因此REL
为false,因此(REL) ? "RELEASE_VER" : "DEBUG_VER"
应该产生“DEBUG_VER”。
这正是你所观察到的,所以如果你期望看到“RELEASE_VER”,你应该设置:
public static final boolean DEBUG = false;
试试看看会发生什么。