DEBUG 和 RELEASE 在 Java (Eclipse) 中构建?

DEBUG and RELEASE builds in Java (Eclipse)?

Java 和 Eclipse 的新手(但对 Visual Studio 和 Delphi 有经验)。使用 Eclipse Mars (4.5),无法找到如何设置构建配置(DEBUG 或 RELEASE)。几个相关问题:

DEBUG/RELEASE 在 java 中不完全支持。但是有一些事实需要记住,还有一些其他方法可以完成同一件事的各个部分。

java 的创建者认为,无论外部因素如何,让每个编译单元都生成完全相同的字节码是有很大好处的,因此 Java 没有 pre-processor .

java 与您熟悉的 DEBUG/RELEASE 最接近的是 assert 关键字。您可以通过向 VM 提供 -assertionsenabled(简称 -ea)参数来控制是否评估断言。阅读它,并阅读如何将参数传递给 VM。

注意 VM 参数是运行时参数,它们与编译器无关,这意味着断言总是由编译器发出到字节码中,如果你不提供 -ea,那么运行时将避免评估它们。因此,至少仍然会有一个隐藏的 if( assertionsEnabled ) { ... } 语句为每个断言执行。

另一件值得记住的事情是 public static final 变量被视为 compile-time 常量, 编译器可能会避免为由if( false ) 子句。然而,源代码将始终被编译,因此它必须是正确的,尽管实际上不会生成字节码。

因此,您可以将全局变量定义为 public static final boolean DEBUG = true 来控制所有调试代码,但您必须在源代码中手动更改它并重建项目才能生成发布版本; java 特别避免提供任何其他方式来完成此操作。

此外,请注意 if( false )(以及扩展名 if( DEBUG ))会发出有关条件始终为真或始终为假的警告,因此我不喜欢使用它。

java 的理念是,我们通常不关心性能到偏执的程度,以至于想要完全控制 DEBUG 和 RELEASE 之间微小的性能差异。通常,assert 关键字是所有需要的,实际上(令我沮丧的是)大多数 java 人由于各种(蹩脚的,恕我直言)原因甚至不使用 assert。

至于发出调试信息,绝大多数调试信息无论如何都会生成,因为它必须在运行时通过反射可用。我知道有一件你可以控制的小事:-parameters 编译器选项,但它真的无关紧要,而且编译器的未来版本可能会弃用该选项并包含它所包含的功能控件作为标准行为。

这也意味着 java 代码可以 reverse-engineered 比 C++ 代码更容易,因此存在 java 混淆器通过 identifier-mangling 阶段,然后将其发送到 java 编译器,以减少字节码文件中的有用信息量。

你可能会高兴地知道,由于 JIT 的存在,这一切还不算太糟糕:字节码被 VM 编译成机器代码,并且在那个阶段进行了许多优化,所以你总是从中受益,不仅仅是发布。

关于检测断言是否开启,可以使用如下代码:

static boolean areAssertionsEnabled()
{
    //noinspection UnusedAssignment
    boolean b = false;
    //noinspection ConstantConditions,AssertWithSideEffects
    assert b = true;
    //noinspection ConstantConditions
    return b;
}

noinspection 东西用于抑制 IntelliJ IDEA 中的警告,java IDE 远优于 Eclipse。如果你坚持使用 Eclipse,你将不得不为它找到等效的警告抑制机制。