学习如何在 Java 代码中启用和禁用断言

Merlin 的魔力:使用断言 英文原文
内容:
断言关键字
启用断言
更多使用断言的方法
通过编程启用
小结
参考资料
关于作者
对本文的评价
相关内容:
Incremental development with Ant and JUnit
Merlin 的魔力专栏
Documenting Java member functions
alphaWorks 的 JATE
在 Java 专区还有:
教学
工具与产品
代码与组件
所有文章
实用技巧
学习如何在 Java 代码中启用和禁用断言

John Zukowskijaz@zukowski.net
总裁,JZ Ventures, Inc.
2002 年 2 月

Merlin 为改进的方法增添了提供可选的前置条件和后置条件验证的能力。虽然缺省情况下在运行时会禁用断言功能,但是可以启用它来检查错误条件。在这篇 Merlin 的魔力中,John Zukowski 带您去了解通过命令行和编程的方法来向代码添加断言检查以及如何启用和禁用断言的一些基本知识。请通过单击文章顶部或底部的 讨论在 论坛上同作者及其他读者分享您对本文的想法。

断言功能是 Java 1.4 发行版所具有的为人热切期盼的一项新功能。您可以将该功能看作是异常处理的一种高级形式。断言表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式的值为真。例如,程序员可能会在程序中包含断言,使您永远也不会到达 switch 语句中的 default 条件。

由于可以在任何时候启用或禁用断言验证,因此可以在测试时启用断言验证而部署时禁用断言验证。同样,程序投入运行后,最终用户在碰到问题时可以重新启用断言。

在本专栏文章中,通过演示两种不同的方式来启用和禁用断言以便优化代码测试和性能,我将向您讲述一些有关向代码中添加断言的基本知识。

断言关键字
断言检查就象异常处理,但是当断言失败时,却不会抛出异常,而会抛出一个 AssertionError。象所有错误一样,从断言故障中恢复(如果不是不可能的话)就是很困难的,因为这样的故障表明程序状态已偏离正常操作参数。

使用断言的两个基本构造如下:


assert booleanExpression;
assert booleanExpression : message;

注意,可选的消息(message)将作为错误抛出的结果显示出来。

可以将断言语句作为方法的前置条件或后置条件来添加。也可以建立布尔表达式以调用方法。同样,您可能希望向 if 块中的 else 条件添加断言,这里已经设置了该条件,或者向 switch 语句中的缺省情况中添加断言,使缺省情况永远不可能到达。assert 关键字的唯一限制在于它必须位于可执行块中。不能将断言同实例的类变量声明一块使用,但却可以将其置于任何方法内。

启用断言
如果您想使用断言,那么您必须使用一些专门的命令行选项来编译并运行程序。由于编译器运行于 1.3 兼容模式,因此您必须显式地要求运行在 1.4 模式下。要编译带有断言的程序,只需向 Java 编译器传递 -source 1.4 设置。缺省情况下,会禁用断言检查,因此在运行时您也要显式地启用这一功能。请使用 -enableassertions 选项或更短的 -ea 选项来启用断言检查。

下面的简单示例向您介绍了向程序中添加断言检查的一些必要步骤。它检查命令行参数的数目,如果值不为 0 时,则报告问题:


public class AssertTest {
  public static void main(String args[]) {
    assert args.length == 0 : args.length + " != 0";
    System.out.println(args.length);
  }
}

确保按如下所示使用 -source 选项来编译该程序:


javac -source 1.4 AssertTest.java

要测试该程序,只需运行该程序并传递命令行参数:


java AssertTest 1 2 3 4

因为该程序是用来显示参数的数目,所以该测试程序将显示四。由于在缺省情况下禁用了断言检查,因此不会检测到任何断言错误。

现在,请带有启用断言检查运行该程序:


java -ea AssertTest 1 2 3 4

带启用断言检查运行程序产生下面的错误报告:


Exception in thread "main" java.lang.AssertionError: 1 != 0
        at AssertTest.main(AssertTest.java:3)

这就是整个断言功能的实质。这里,最难的部分是确定将 assert 关键字放在何处以及条件是什么。

其它使用断言的方法
对于整个程序,虽然 -ea 选项是一种启用断言的简易方法,但也可以使用其它选项。另外,-ea 不能用于系统类;由于那个原因,需要使用 -enablesystemassertions,或者更简单些,使用 -esa

要对整个包树(即包和子包)启用断言,只需在 -ea 选项后面加上一个冒号,包的名称和一个省略号(...)。例如,下面的语法将对 net.zukowski.ibm 包及其所有的子包启用断言检查:


java -ea:net.zukowski.ibm... EclipseTest

对于特定类,需要指定完整的类名而不是在包名称之后加省略号。

如果希望对包的整个集合启用断言检查,而不是某个类或包(树)启用断言检查,则 -da 标记就能满足这一要求(“-da”是 -disableassertions 的缩写)。只需列出启用和禁用选项,您只需做这些。例如,下面的语法对 net.zukowski.ibm 包启用断言检查,但不对 net.zukowski.ibm.BeanUtils 类启用断言检查:


java -ea:net.zukowski.ibm... -da:net.zukowski.ibm.BeanUtils EclipseTest

通过编程启用断言
除了从命令行启用断言检查之外,您也可以通过编程启用(或禁用)检查。由于这仅影响将来装入的类,因此不能随意地关闭或打开它。

类的 ClassLoader 使用下面四种方法控制断言的启用和禁用:

  • public void setDefaultAssertionStatus(boolean enabled): 该方法设置由类装入器装入的包和类的缺省状态。可以通过设置特定的包和类选项来覆盖该设置。

  • public void setPackageAssertionStatus(String packageName, boolean enabled):要覆盖包和其所有的子包的状态,传入包名和启用状态。

  • public void setClassAssertionStatus(String className, boolean enabled):要覆盖特定类的状态,传入全限定类名和启用状态。

  • public void clearAssertionStatus():该方法将所有包和类的设置重设为 false,然后将类装入器也重设为 false。

要获取类的类装入器,调用 Class 对象的 getClassLoader() 方法。对非静态方法使用以下命令:


ClassLoader loader = getClass().getClassLoader();

对于静态方法,不能调用 getClass(),因为没有实例,所以只需把 .class 添加到当前类名的后面,如下所示:


ClassLoader loader = EclipseTest.class.getClassLoader();

请记住这仅影响更改之后装入的类。在大多数情况下,您会发现您是从命令行启用断言。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值