[转载]Merlin 的魔力: 使用断言

Merlin 的魔力: 使用断言


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

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

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

断言关键字

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

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

assert booleanExpression;
assert booleanExpression : message;

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

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


blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


启用断言

如果您想使用断言,那么您必须使用一些专门的命令行选项来编译并运行程序。由于编译器运行于 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 关键字放在何处以及条件是什么。


blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


其它使用断言的方法

对于整个程序,虽然 -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


blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


通过编程启用断言

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

类的 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();

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


blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


小结

您掌握了吧。这就是 Java 1.4 断言功能。有关在何处使用断言这方面的提示,请参阅 参考资料中列出的正式文档中的 Usage Notes部分。使用断言时要记住的关键是可以选择性地启用断言;因此,除了时间差异之外,它们不会有任何副作用。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/374079/viewspace-130116/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/374079/viewspace-130116/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值