13

我知道断言可以在运行时启用/禁用,分别用于调试和生产。但是我发现断言也会增加生成的二进制文件的大小(在下面的示例中约为 100-200 个字节)。

在 C 和 C++ 中,我们可以在编译时通过#define NDEBUGbefore来执行此操作#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);
        }
    }
}

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

4

2 回答 2

4

作为内置编译步骤,这是不可能的。但是,您可以通过在断言周围添加条件块来做到这一点。

有关详细信息,请参阅文章“从类文件中删除所有断言跟踪”

于 2012-06-06T15:34:09.720 回答
2

Personally I would not do the following because of the complexity added to the source code but javac generated the exact same intermediate code for main in the following two fragments:

conditional asserts

class C {
    public final static boolean assertions = false;

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

no asserts

class C {
    public static void main(String[] args) {
    }
}

compiled code

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

EDIT

In fact, it seems to me that this enabling/disabling is a more useful compile-time feature than run-time. I mean, how many end users will enable them?

Its not end users that enable them, it is the customer support that tells the end user to enable them. I do wish though they were enabled, not disabled, by default.

于 2012-06-06T16:07:07.217 回答