Java和Eclipse的新手(但在Visual Studio和Delphi方面经验丰富)。使用Eclipse Mars(4.5)并且无法找到如何设置构建配置(DEBUG或RELEASE)。几个相关问题:
{$IFDEF DBG} CallDebugFunction(); {$ELSE} CallReleaseFunction(); {$ENDIF};
答案 0 :(得分:6)
java中不完全支持DEBUG / RELEASE。但是有一些事实可以记住,还有一些其他方法可以完成同样的事情。
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
关键字是所有需要的,实际上(令我沮丧的是)大多数java人甚至不会因为各种(跛脚,恕我直言)原因而使用断言。
至于发出调试信息,绝大多数调试信息都是生成的,因为它必须在运行时通过反射提供。我知道你可以控制的一件小事:-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中的警告,这是一个远远优于Eclipse的Java IDE。如果您坚持使用Eclipse,则必须为其找到等效的警告抑制机制。