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

4

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

  • Java支持DEBUG / RELEASE吗?
  • 如何在两个配置之间切换?
  • 您能否在构建时检测配置并运行条件代码,例如(使用Delphi作为示例): {$IFDEF DBG} CallDebugFunction(); {$ELSE} CallReleaseFunction(); {$ENDIF};
1个回答

8
DEBUG/RELEASE在Java中并没有受到完全的支持。但是需要记住几个有用的事实,并且还有一些其他方式可以完成同样的事情的部分内容。
Java的创建者决定,每个编译单元产生相同的字节码,而不考虑外部因素,这有很大的好处,因此Java没有预处理器。
Java最接近你熟悉的DEBUG/RELEASE的东西就是assert关键字。你可以通过向VM提供-assertionsenabled (简称-ea)参数来控制是否评估断言。了解它,并阅读如何将参数传递给VM。
请注意,VM参数是运行时参数,与编译器无关,这意味着无论如何都会从编译器发出断言到字节码中,如果您没有提供-ea,则运行时将避免评估它们。因此,至少对于每个断言仍将始终执行一个隐藏的if(assertionsEnabled){...}语句。
另一件值得记住的事情是,public static final变量被视为编译时常量,编译器可能会避免为由if(false)子句控制的源代码生成任何字节码。但源代码仍将编译,因此它必须正确,尽管不会生成任何字节码。
因此,您可以定义一个全局变量作为public static final boolean DEBUG = true,以控制所有调试代码,但是您必须手动更改源代码并重建项目,以生成发布版本;Java明确不提供任何其他方式来完成这一点。
此外,if(false)(以及扩展名为if(DEBUG))将产生有关条件始终为真或始终为假的警告,因此我不喜欢使用它。
Java的哲学通常不会像想要完全控制DEBUG和RELEASE之间微小性能差异的偏执狂那样在乎性能。通常,assert关键字就足够了,实际上(令我沮丧的是),由于各种( IMHO )原因,大多数Java人甚至不使用assert。
至于发出调试信息,绝大多数调试信息都已经生成,因为它必须通过反射在运行时可用。我知道的有一件微小的事情可以控制:编译器选项-parameters,但它确实不重要,并且可能未来版本的编译器会废弃该选项,并将其控制的功能包含为标准行为。
这意味着Java代码比C++代码更容易被逆向工程,因此存在Java混淆器,将代码通过标识符混淆阶段传递给Java编译器,以减少字节码文件中有用信息的数量。
你可能会很高兴知道这并不太糟糕,因为由JIT完成:VM将字节码编译成机器码,并在该阶段执行许多优化,因此您始终受益于它们,而不仅仅是在发布时。
至于检测断言是否启用,您可以使用以下代码:
static boolean areAssertionsEnabled()
{
    //noinspection UnusedAssignment
    boolean b = false;
    //noinspection ConstantConditions,AssertWithSideEffects
    assert b = true;
    //noinspection ConstantConditions
    return b;
}
< p > noinspection 的作用是在 IntelliJ IDEA 中抑制警告,它是一款远比 Eclipse 优秀的 Java IDE。如果你一定要使用 Eclipse,那么你需要找到相应的警告抑制机制。


编译器选项如 -g 系列用于控制生成调试信息,您怎么看? - user85421
我修改了我的答案。 - Mike Nakis
1
这就解释了为什么在Visual Studio和Delphi中我找不到那些显眼的选项!我习惯于DEBUG / RELEASE(并发现它们很有用)...但我可以很容易地适应Java的方式。好答案,谢谢。 - AlainD

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接