Java(Eclipse)中的DEBUG和RELEASE构建



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

  • Java中是否支持DEBUG/RELEASE
  • 如何在两种配置之间切换
  • 你能在构建时检测配置并运行这样的条件代码吗(以Delphi为例):{$IFDEF DBG} CallDebugFunction(); {$ELSE} CallReleaseFunction(); {$ENDIF};
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 ))将产生一个关于条件始终为true或始终为false的警告,所以我不喜欢使用它

java的哲学是,我们通常不关心性能到偏执的程度,以至于希望完全控制DEBUG和RELEASE之间微小的性能差异。一般来说,assert关键字就是所需要的,事实上(令我沮丧的是)由于各种原因(lame,IMHO),大多数java用户甚至不使用assert。

至于发出调试信息,绝大多数调试信息都是生成的,因为它必须在运行时通过反射可用。我知道有一件小事你可以控制:-parameters编译器选项,但它实际上并不重要,而且编译器的未来版本可能会弃用该选项,并将其控制的功能作为标准行为包括在内。

这也意味着java代码可以比C++代码更容易地进行反向工程,因此存在java模糊器,它在将代码发送到java编译器之前,将代码通过标识符篡改阶段,以减少字节码文件中有用信息的数量。

您可能很高兴知道,由于JITting,这一切都还不错:字节码由VM编译成机器代码,并且在那个阶段进行了许多优化,所以您总是从中受益,而不仅仅是在RELEASE上。

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

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

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

最新更新