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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5558731/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 11:39:55  来源:igfitidea点击:

How to programmatically enable assert?

javaconfigurationassertions

提问by Saideira

How can I programmatically enable assert for particular classes, instead of specifying command line param "-ea"?

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

public class TestAssert {

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


    public static void main(String []args) {
        assert foo.length == 10;
    }
}

采纳答案by Bill K

This was a comment to @bala's good answer, but it got too long.

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

If you just enable assertions then call your main class--your main class will be loaded before assertions are enabled so you will probably need a loader that doesn't reference anything else in your code directly. It can set the assertions on then load the rest of the code via reflection.

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

If assertions aren't enabled when the class is loaded then they should be "Compiled Out" immediately so you are not going to be able to toggle them on and off. If you want to toggle them then you don't want assertions at all.

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

Due to runtime compiling, something like this:

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

public myAssertNotNull(Object o) {
    if(checkArguments) 
        if(o == null)
            throw new IllegalArgumentException("Assertion Failed");
}

Should work nearly as fast as assertions because if the code is executed a lot and checkArguments is false and doesn't change then the entire method call could be compiled out at runtime which will have the same basic effect as an assertion (This performance depends on the VM).

应该几乎和断言一样快地工作,因为如果代码被执行了很多并且 checkArguments 是假的并且没有改变,那么整个方法调用可以在运行时编译出来,这将具有与断言相同的基本效果(这种性能取决于虚拟机)。

回答by Bala R

Try

尝试

ClassLoader loader = getClass().getClassLoader();
setDefaultAssertionStatus(true);

or

或者

ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);

EDIT:

编辑:

based on the comments

根据评论

    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;
    }
}

回答by mBardos

You can enable/disable assertions programmatically too:
http://download.oracle.com/docs/cd/E19683-01/806-7930/assert-5/index.html

您也可以以编程方式启用/禁用断言:http:
//download.oracle.com/docs/cd/E19683-01/806-7930/assert-5/index.html

回答by Rajarshee Mitra

The simplest & best way can be:

最简单和最好的方法可以是:

public static void assertion(boolean condition, String conditionFailureMessage)
{
    if(!condition)
        throw new AssertionError(conditionFailureMessage);
}

No need to set -ea as VM argument .

无需将 -ea 设置为 VM 参数。

call the function like :

调用函数,如:

assertion(sum>=n,"sum cannot be less than n");

If assertion fails, code will give AssertionError, else code will run safely.

如果断言失败,代码将给出 AssertionError,否则代码将安全运行。

回答by SDJ

It is possible to enable or disable assertions using reflection. As usual with reflection, the solution is fragile and may not be appropriate for all usage scenarios. However, if applicable and acceptable, it is more flexible than setClassAssertionStatusbecause it allows to enable/disable assertions checks at various points in the execution, even after the class is initialized.

可以使用反射来启用或禁用断言。与反射一样,该解决方案很脆弱,可能不适用于所有使用场景。然而,如果适用和可接受,它比它更灵活,setClassAssertionStatus因为它允许在执行的各个点启用/禁用断言检查,即使在类初始化之后

This technique requires a compiler that generates a synthetic static field to indicate whether assertions are enabled or not. For example, both javac and the Eclipse compiler generate field $assertionsDisabledfor any class that contains an assertstatement.

这种技术需要一个编译器来生成一个综合静态字段来指示是否启用了断言。例如,javac 和 Eclipse 编译器都会$assertionsDisabled为包含assert语句的任何类生成字段。

This can be verified as follows:

这可以验证如下:

public class A {
    public static void main(String[] args) {
        assert false;
        System.out.println(Arrays.toString(A.class.getDeclaredFields()));
    }
}

Setting the desired assertion status just comes down to setting this field (note the inverted boolean value):

设置所需的断言状态归结为设置此字段(注意反转的布尔值):

// Helper method in any class
public static void setAssertionsEnabled(Class<?> clazz, boolean value) 
    throws ReflectiveOperationException
{
    Field field = clazz.getDeclaredField("$assertionsDisabled");
    field.setAccessible(true);
    Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
    field.set(Test.class, !value);
}