我知道断言可以在运行时启用/禁用,分别用于调试和生成。但是我发现断言也增加了生成的二进制文件的大小(在下面的例子中约为100-200字节)。
在C和C ++中,我们可以在编译时通过#define NDEBUG
之前#include <assert.h>
来完成此操作。
Java编译器有没有办法自动执行此操作?我想将它们留在源代码中以便以后进行调试。但我也不希望生成的二进制文件大于必要的大小(我们有一个大小限制作为设计要求)。
C代码:
//#define NDEBUG
#include <assert.h>
int main(void) {
assert(0); // +200 bytes without NDEBUG, 0 with NDEBUG
return 0;
}
Java代码:
public class Test {
public static void main(String[] args) {
assert(System.nanoTime()==0); // increases binary size by about 200 bytes
}
}
回应bn。的回答:
public class Test2 {
public static final boolean assertions = false;
public static void main(String[] args) {
if(assertions) {
assert(System.nanoTime()==0);
}
}
}
编辑:事实上,在我看来,这种启用/禁用是比运行时更有用的编译时功能。我的意思是,有多少最终用户会启用它们?就程序员而言,在调试过程中,他/她可能会重新编译代码。
答案 0 :(得分:4)
这不可能作为内置编译步骤。但是,您可以通过在断言周围添加条件块来完成此操作。
有关详细信息,请参阅文章"Removing all Trace of Assertions from Class Files"。
答案 1 :(得分:2)
我个人不会这样做,因为源代码添加了复杂性,但javac在以下两个片段中为main
生成了完全相同的中间代码:
有条件断言
class C {
public final static boolean assertions = false;
public static void main(String[] args) {
if(assertions) {
assert(System.nanoTime()==0);
}
}
}
没有断言
class C {
public static void main(String[] args) {
}
}
已编译的代码
public static void main(java.lang.String[]);
Code:
0: return
LineNumberTable:
line 3: 0
修改强>
事实上,在我看来,这种启用/禁用更有用 编译时功能比运行时。我的意思是,有多少终端用户会 启用它们吗?
它不是支持它们的最终用户,它是客户支持,告诉最终用户启用它们。我希望默认情况下它们已启用,而非禁用。