编译没有断言

tsk*_*zzy 13 java performance assert

我知道断言可以在运行时启用/禁用,分别用于调试和生成.但是我发现断言也增加了生成的二进制文件的大小(在下面的例子中约为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;
}
Run Code Online (Sandbox Code Playgroud)

Java代码:

public class Test {
    public static void main(String[] args) {
        assert(System.nanoTime()==0); // increases binary size by about 200 bytes
    }
}
Run Code Online (Sandbox Code Playgroud)

回应bn.的答案:

public class Test2 {
    public static final boolean assertions = false;

    public static void main(String[] args) {
        if(assertions) {
            assert(System.nanoTime()==0);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:事实上,在我看来,这种启用/禁用是比运行时更有用的编译时功能.我的意思是,有多少最终用户会启用它们?就程序员而言,在调试过程中,他/她可能会重新编译代码.

Mis*_*ble 2

main 就我个人而言,我不会执行以下操作,因为源代码会增加复杂性,但 javac在以下两个片段中生成了完全相同的中间代码:

条件断言

class C {
    public final static boolean assertions = false;

    public static void main(String[] args) {
        if(assertions) {
            assert(System.nanoTime()==0);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

没有断言

class C {
    public static void main(String[] args) {
    }
}
Run Code Online (Sandbox Code Playgroud)

编译后的代码

  public static void main(java.lang.String[]);
    Code:
       0: return        
    LineNumberTable:
      line 3: 0
Run Code Online (Sandbox Code Playgroud)

编辑

事实上,在我看来,这种启用/禁用是一个比运行时更有用的编译时功能。我的意思是,有多少最终用户会启用它们?

不是最终用户启用它们,而是客户支持告诉最终用户启用它们。我确实希望默认情况下它们是启用的,而不是禁用的。