如何以编程方式启用断言?

Sai*_*ira 30 java configuration assertions

如何以编程方式为特定类启用断言,而不是指定命令行参数"-ea"?

public class TestAssert {

    private static final int foo[] = new int[]{4,5,67};


    public static void main(String []args) {
        assert foo.length == 10;
    }
}
Run Code Online (Sandbox Code Playgroud)

Bal*_*a R 13

尝试

ClassLoader loader = getClass().getClassLoader();
setDefaultAssertionStatus(true);
Run Code Online (Sandbox Code Playgroud)

要么

ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);
Run Code Online (Sandbox Code Playgroud)

编辑:

根据评论

    ClassLoader loader = ClassLoader.getSystemClassLoader();
    loader.setDefaultAssertionStatus(true);
    Class<?> c = loader.loadClass("MyClass");
    MyClass myObj = (MyClass) c.newInstance();


public class MyClass {

    private static final int foo[] = new int[]{4,5,67};
    MyClass()
    {
        assert foo.length == 10;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 由于您可以想象“基于评论”在评论被标记为过时后不起作用,因此最好正确记录原因。为什么要通过反射创建 MyClass 的实例? (2认同)

Bil*_*l K 9

这是对@ bala的好答案的评论,但它太长了.

如果你只是启用断言然后调用你的主类 - 你的主类将在启用断言之前加载,所以你可能需要一个不直接引用代码中任何其他内容的加载器.它可以设置断言,然后通过反射加载其余的代码.

如果在加载类时未启用断言,那么它们应立即"编译出",这样您就无法打开和关闭它们.如果你想切换它们,那么你根本不需要断言.

由于运行时编译,这样的事情:

public myAssertNotNull(Object o) {
    if(checkArguments) 
        if(o == null)
            throw new IllegalArgumentException("Assertion Failed");
}
Run Code Online (Sandbox Code Playgroud)

应该像断言一样快速工作,因为如果代码执行很多并且checkArguments是假的并且没有改变那么整个方法调用可以在运行时编译出来,这将具有与断言相同的基本效果(此性能取决于VM).