在C / C ++中,我可以使用如下
int main()
{
#if defined(DEBUG_MODE)
// The following code may contain sensitive messages.
// But these sensitive messages won't be compiled into the release binary.
A lot of debugging mode code here, which will bloat the final executable.
......
#endif
}
如何用Java做同样的事情?
我想要的是减少类的最终大小并删除所有敏感的调试消息。
也就是说,以下Java代码不是我想要的。
class A
{
public void f()
{
if (DEBUG_MODE)
{ // The following code may contain sensitive messages.
// So I want to remove them before release.
A lot of debugging mode code here, which will bloat the final executable.
......
}
}
}
答案 0 :(得分:2)
你可以做的一件事是使用断言。这不会阻止代码到达您的最终Jar文件,但它将允许您告诉Java完全忽略此代码;只有在Java VM上使用-ea标志时才会执行断言。
public class Test {
public static main(String... args) {
assert args.length == 3;
assert debug();
process();
}
// always runs
public static void process() {
// process
}
// only runs with -ea enabled
public static boolean debug() {
// debug
}
}
因此,在调试时,确保设置-ea标志,并且运行断言,在生产代码中运行时,不要设置-ea标志,调试代码将被忽略。
这个例子是荒谬的,但重点是展示调试代码如何不影响生产代码。
答案 1 :(得分:1)
由于许多原因,这在Java中通常是不受欢迎的,但如果你真的需要完全删除,最好的办法是使用static final boolean
。
public static final boolean Debug = false;
public void test() {
if ( Debug ) {
// Debug stuff here - usually will not be included in the .class file if Debug is false.
}
}
这通常(但据我所知,无法保证)完全删除所附的代码。
另一种方法是使用某种形式的后期绑定机制来动态加载调试类,同时为发布代码留下空存根。
答案 2 :(得分:1)
如果代码中的DEBUG_MODE
是static final boolean
,则可以在“仅优化”模式下使用ProGuard。它将清除可执行文件中的所有if (false)
代码。
答案 3 :(得分:0)
最终的可执行文件是压缩的,除非您有嵌入式设备或智能手机,否则很少需要担心它的大小。即使使用调试信息,您可能会发现使用压缩和更高级别的抽象,它仍然比相同的C代码小。
例如,额外的MB成本会有多大差异?我们是否在讨论需要额外的1000美元硬件?
一般来说,JIT会根据当时的状态在运行时删除代码。例如什么时候打开调试标志。