服务时间:8:30-18:00

首页 >java学习网

什么时候用assert

发布时间:2022-11-26 13:38 字数:3172字 阅读:125

什么时候用assert

考点:考察求职者对Java断言的理解。

出现频率:★★★★

【面试题解析】

assert是在J2SE 1.4中引入的新特性,assertion是在代码中包含的一种布尔型状态,程序员认为这个状态是true。一般来说,assert在开发的时候是检查程序的安全性的,在发布的时候通常都不使用assert。

首先,有必要从一个例子说起,示例代码如下:


        public class AssertTest
        {
        public static void main(String[] args)
        {
          AssertTest at = new AssertTest();
          at.assertMe(true);
          at.assertMe(false);
        }

        private  void assertMe(boolean boo)
        {
          assert boo?true:false;
          System.out.println("true condition");
        }
        }


程序中包含了assert的话,要用“javac -source 1.4 xxx.java”来编译,否则编译器会报错。要想让assert的部分运行的话,要使用“java -ea xxx”来运行,否则包含assert的行会被忽略。在命令行输入如下命令:


        javac -source 1.4 AssertTest.java
        java -ea AssertTest


输出结果如下:


        true condition
        Exception in thread "main" java.lang.AssertionError
                at AssertTest.assertMe(AssertTest.java:13)
                at AssertTest.main(AssertTest.java:7)


当运行at.assertMe(true)的时候,由于“assert boo?true:false”相当于“assert true;”,因此没有任何问题,程序往下执行,打印出“true condition”,但是执行at.assertMe(false)的时候相当于“assert false”,这个时候解释器就会抛出AssertionError,程序就终止了。AssertionError是继承自Error的,可以在程序中捕获它,然后程序可以继续执行。示例代码如下:

        public class AssertTest
        {
        public static void main(String[] args)
        {
          AssertTest at = new AssertTest();
          try
          {
          at.assertMe(true);
          at.assertMe(false);
          }
          catch(AssertionError ae)
          {
          System.out.println("AsseriontError catched");
          }
          System.out.println("go on");

        }
        private  void assertMe(boolean boo)
        {
          assert boo?true:false;
          System.out.println("true condition");
        }

        }

assert还有另外一种表达的方式,就是“assert eXP1:exp2;“,其中exp1是个boolean返回值的表达式,而exp2是原始的数据类型或者对象都可以。示例代码如下:

          boolean boo = true;
          String str = null;
          assert boo = false:str="error";

刚开始讲的assert exp1的形式,当exp1是false的时候,AssertionError的默认构造器会被调用。但是对“assert exp1:exp2”这样的形式,当exp1为true的时候,后面的exp2被忽略,如果false的话,后面的表达式的结果会被计算出来,并作为AssertionError的构造器参数。示例如下:

        public class AssertTest
        {
        public static void main(String[] args)
        {
          AssertTest at = new AssertTest();
          at.assertMe(true);
          at.assertMe(false);

        }
        private  void assertMe(boolean boo)
        {
          String s = null;
          assert boo?true:false:s = "hello world";
          System.out.println("true condition");
        }
        }

运行结果如下:

        true condition
        Exception in thread "main" java.lang.AssertionError: hello world
                at AssertTest.assertMe(AssertTest.java:14)
                at AssertTest.main(AssertTest.java:7)

Assert最好不要滥用,原因是assert并不一定都是enable的,下面两种情况就不应该用assert。

不要在public的方法里面检查参数是不是为null之类的操作,示例代码如下:

        public int get(String s)
          {
              assert s != null;
          }

如果需要检查,也最好通过“if s = null”抛出NullPointerException来检查,不要用assert来检查方法操作的返回值来判断方法操作的结果。

例如“assert list.removeAll();”这样看起来好像没有问题,但是如果assert被disable,语句就不会被执行了,所以removeAll()操作就没有被执行,可以这样代替:

        boolean boo = list.removeAl();
        assert boo;

注意:assert是SCJP1.4的考试内容,所以还是非常有必要熟悉和掌握的。

参考答案:

断言是一个包含布尔表达式的语句,在执行这个语句时,假定该表达式为true。如果表达式计算为false,那么系统会报告一个Assertionerror。它用于调试目的:

        assert(a > 0); // throws an Assertionerror if a <= 0

断言可以有两种形式:

        assert Expression1 ;
        assert Expression1 : Expression2 ;

• Expression1应该总是产生一个布尔值。

• Expression2可以是得出一个值的任意表达式。这个值用于生成显示更多调试信息的String消息。

断言在默认情况下是禁用的。要在编译时启用断言,需要使用source 1.4标记:

        javac -source 1.4 Test.java

要在运行时启用断言,可使用-enableassertions或者-ea标记。

要在运行时选择禁用断言,可使用-da或者-disableassertions标记。

要在系统类中启用断言,可使用-esa或者-dsa标记,还可以在包的基础上启用或者禁用断言。

可以在预计正常情况下不会到达的任何位置上放置断言。断言可以用于验证传递给私有方法的参数。不过,断言不应该用于验证传递给公有方法的参数,因为不管是否启用了断言,公有方法都必须检查其参数。

不过,既可以在公有方法中,也可以在非公有方法中利用断言测试后置条件。另外,断言不应该以任何方式改变程序的状态。