Java 编译器不会优化静态最终字符串。为什么?

发布于 2024-12-29 10:45:10 字数 370 浏览 0 评论 0原文

我的应用程序中有以下代码:

  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 文件(通过 Proguard 导出时)中完全消除 "DEBUG_VER" 字符串,但是当我检查 .apk 文件时,我在那里看到“DEBUG_VER”字符串。

为什么?我缺少什么?我做错了什么?

I have the following code in my app:

  public static final boolean DEBUG = true;
  public static final boolean REL = !DEBUG;

  private static final String DEBUG_OR_RELEASE = (REL) ? "RELEASE_VER" : "DEBUG_VER";

I thought that the Java compiler will eliminate the "DEBUG_VER" string completely from the resulting .apk file (when exported via Proguard) but when I examine the .apk file, I see the "DEBUG_VER" string in there.

Why? What am I missing? What did I do wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

同尘 2025-01-05 10:45:11

即使变量设置为 true,它仍在运行。 ?: 语句是可执行和操作代码的一部分,并且由于 Java 没有预编译器,因此它将在每次编译时运行

Java 不会自动推断和简化操作,即使逻辑上每次迭代的操作都是相同的。

It's still being run even when the variable is set to true. ?: statements are part of executable and operational code, and since Java doesn't have a precompiler, it will be run every time you compile.

Java does not infer and simplify operations automatically, even if logically the operations are the same each iteration.

戒ㄋ 2025-01-05 10:45:10

编译为java字节码并没有进行优化(除了极少数例外)。

许多书籍为了简化而指出“编译”阶段是优化发生的时间,但这是错误的。当优化真正发生时,是在 JVM 处理字节码文件的时候。因此,需要澄清的是:在将字节码编译为机器本机代码时可能会发生优化,这是由 JVM 工具完成的。

有时根本没有优化(JVM 在解释模式下工作)。有时 JIT(Just In Time 编译器)会进行一些优化。有时,自适应优化器会负责优化(不仅是优化,而且还会在执行其他操作时分析代码执行情况)。

所以最后,你的文件没有任何问题。这就是java世界的运作方式。

“但为什么?” ——你可能会问。将这些“无用”信息保留在字节码中的原因是,您永远无法确定可以消除多少代码,以便不同 JVM 提供的优化仍然可以有效地工作。最好的方法就是不删除任何信息并让优化器完成其工作。

Compilation to java bytecode is not making optimization (except a very few exceptions).

Many books state for simplification that the 'compilation' phase is when optimization occurs, but it is wrong. When the optimization really takes place, is while bytecode files are processed by JVM. So for the clearance: optimization may occur at the time of compilation bytecode to machine native code, which is done by JVM tools.

Sometimes there is no optimization at all (JVM works in interpreting mode). Sometimes there is some optimization made by JIT (Just In Time complier). And sometimes adaptative optimizer takes care of the optimization (not only optimizing but also profiling code execution in case of additional operations to be performed).

So finally, there is nothing wrong with your file. It's just how java world works.

"But why?" -- you may ask. The reason to keep this 'useless' information in bytecode is because you would never be sure how many code can you eliminate so the optimization provided by different JVM could still work efficient. The best way is just to not erase any information and let the optimizers to do their job.

自演自醉 2025-01-05 10:45:10

根据您发布的内容, DEBUG 为 true,因此 REL 为 false,所以 (REL) ? "RELEASE_VER" : "DEBUG_VER" 应产生“DEBUG_VER”。

这正是您所观察到的,因此如果您希望看到“RELEASE_VER”,您应该设置:

public static final boolean DEBUG = false;

尝试一下,看看会发生什么。

According to what you posted, DEBUG is true, so REL is false, so (REL) ? "RELEASE_VER" : "DEBUG_VER" should yield "DEBUG_VER".

This is exactly what you are observing so if you are expecting to see "RELEASE_VER" instead, you should set:

public static final boolean DEBUG = false;

Try that and see what happens.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文