Java和Eclipse新手(但熟悉Visual Studio和Delphi)。使用EclipseMars(4.5),无法找到如何设置构建配置(DEBUG或RELEASE)。几个相关问题:
- Java中是否支持DEBUG/RELEASE
- 如何在两种配置之间切换
- 你能在构建时检测配置并运行这样的条件代码吗(以Delphi为例):
{$IFDEF DBG} CallDebugFunction(); {$ELSE} CallReleaseFunction(); {$ENDIF};
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,你将不得不为它找到等效的警告抑制机制