Java基础—assert断言(一)

整理自:
java基础之断言细谈(比较清楚和全面,可先看这个博客!!!)
java assert断言的用法
java断言机制
Java断言机制
java断言机制(assert)
Java核心技术 卷I
断言与异常(Assertion Vs Exception)(区别断言和异常的使用场景!!!)
!另附JUnit中Assert简单介绍

一、何为断言

断言机制:允许java开发者在代码中加入一些检查语句,主要用于程序调试目的。
1.断言机制在用户定义的boolean表达式结果为false时抛出一个error对象,其类型为AssertionError;
2.当我们需要在约定的条件不成立时中断当前操作的话,可以使用断言;
3.作为Error的一种,断言失败可不捕获处理或者声明抛出,一旦出现了则终止程序、不必进行补救或恢复

assert关键字是在JDK1.4才被添加,用于程序的调试。用法有两种:

1.assert expression1;

expression1是逻辑运算表达式,如果expression1为true,表示断言成功,程序继续执行。如果为false,会抛出AssertionError,AssertionError继承Error类,Error类与我们经常用到的Exception类都是集成于Throwable类。AssertionError由于是错误,所以可以不捕获,但不推荐这样做,因为那样会使你的系统进入不稳定状态。

public static void main (String[] args) {
   boolean flag = 1>2;
   assert flag;
}
2.assert expression1:expression2;

用法与1相同,但添加了表达式expression2,当AssertionError发生时,该表达式将被传入AssertionError的构造器,并转换成一个消息字符串。

public static void main (String[] args) {
	boolean flag = 1>2;
	assert flag : "flag is false";
}

注意
1、一种特殊情况是,如果在计算表达式时,表达式本身抛出Exception,那么assert将停止运行,而抛出这个Exception。
2、Expression2的唯一目的是产生一个消息字符串,AssertionError对象并不存储表达式Expression2的值,因此你不可能在以后获取它。

使用assert 我们不用再调试时使用if或System.out来输出调试信息,当程序正式发布就不用再去删除这些调试信息了。而assert可以通过参数-da(默认)使程序不进行断言判断

二、启用和禁用断言

本部分可详见《Java核心技术 I》P286
默认情况下,断言被禁用。
可以在运行程序时用-enableassertions-ea选项启用:java -enableassertions MyAppClassjava -ea MyAppClass
也可用选项-disableassertions-da禁用断言:java -disableassertions MyAppClassjava -da MyAppClass
需要注意的是,在启用或禁用断言时,不必重新编译程序。启用或禁用断言是类加载器的功能。当断言被禁用时,类加载器将跳过断言代码。

java -ea:MyClass -ea:com.mycompany.mylib… MyApp 用于开启MyClass类以及在com.mycompany.mylib包及其子包中所有类的断言;
java -ea:… -da:MyClass MyApp 开启默认包中除MyClass类的断言。???

然而, 启用和禁用所有断言的-ea-da开关不能应用到那些没有类加载器的“系统类”上。对于这些系统类来说,需使用-enablesystemassertions/-esa开关启用断言。
在这里插入图片描述
在eclipse当中:run configurations->arguments->vm arguments中添加 -ea

三、断言使用

Java中有3种处理系统错误的机制

  • 抛出异常
  • 日志
  • 使用断言

关于断言,牢记

  1. 断言失败是致命的、不可恢复的错误;
  2. 断言检查只用于开发和测试阶段。

Java断言的特点是:断言失败时会抛出AssertionError,导致程序结束退出。因此,断言不能用于可恢复的程序错误,只应该用于开发和测试阶段程序内部错误定位。

对于可恢复的程序错误,不应该使用断言。例如:

void sort(int[] arr) {
    assert arr != null;
}

应该抛出异常并在上层捕获:

void sort(int[] arr) {
    if (x == null) {
        throw new IllegalArgumentException("array cannot be null");
    }
}

常见的断言特性:

  • 前置条件断言:代码执行之前必须具备的特性
  • 后置条件断言:代码执行之后必须具备的特性
  • 前后不变断言:代码执行前后不能变化的特性

断言使用场景

  1. 变量值明确
    变量值如果很确定是某个值,则可以用断言。
  2. 执行不到的语句
    可在正常情况下程序不会到达的地方放置断言,例如没有default的switch,则default可加上断言。
  3. 测试前置条件、后置条件
  4. 检查类的状态
    加一个内部方法,返回布尔值,当检查类状态正常时返回true。

不要用断言场景

  1. 不要用断言做参数检查
    因为无论断言是启用还是禁用,都必须进行参数检查的,而断言是可能被禁用的。并且断言报出的AssertionError异常,不能准确反馈运行时异常(例如IllegalArgumentException,IndexOutOfBoundsException或NullPointerException)。
  2. 不要用断言来完成程序正确操作所需的任何工作
    例如,假设你想要从列表名称中删除所有空元素,并且知道该列表包含一个或多个空值。
    错误做法:
    assert names.remove(null); //行为包含在断言中,当断言被启用时,程序会正常工作,但在禁用时会失败,因为它不再从列表中删除空元素。
    正确做法:
    boolean nullsRemoved = names.remove(null); assert nullsRemoved; //动作先于断言
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值