分享
 
 
 

J2SE1.4中assertion功能介绍

王朝java/jsp·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

作者: 甲子

摘要

J2SE 1.4 在JAVA中新增添了assertion(暂译作断定)功能。 最简单的情形下,在JAVA代码中任一行可以写入一条布尔表达式, 在这一行代码的最前面加上assert关键字,就可以实现这样的功能: 如果表达式为真,则代码继续执行;否则,抛出异常。为了实现这项功能, 在JAVA中新添加了assert关键字,AssertionError类, java.lang.ClassLoader中增加了几个新的方法。 本文章详细介绍了assert关键字的使用, 从命令行控制assertion功能,从代码内部控制assertion功能,以及何时使用assertion功能等内容。下文中提到assert时特指assert关键字,而提到assertion则表示断定语句或断定功能。

assertion功能提供了一种在代码中进行正确性检查的机制,这种检查通常用于开发和调试阶段,到了软件完成部署后就可以关闭。这使得程序员可以在代码中加入调试检查语句,同时又可以在软件部署后关闭该功能而避免对软件速度和内存消耗的影响。基本上,assertion功能就是JAVA中的一种新的错误检查机制,只不过这项功能可以根据需要关闭。

通常在C和C++中,断定功能语句是可以通过预处理过程而不编译进最终的执行代码,由于JAVA中没有宏功能,所以在以前的java版本中断定功能没有被广泛的使用,在JDK1.4中通过增加assert关键字改变了这种状况。

这项新功能最重要的特点是断定语句可以在运行时任意的开启或关闭,这意味着这些起错误检查功能的语句不必在开发过程结束后从源代码中删除。

assertion语法非常简单,但正确的使用能帮助我们编写出健壮(ROBAST)可靠的代码。这篇文章中,我们不仅学习如何编写assertion语句,更要讨论应该在什么情况下使用assertion语句。

一、assertion语法基本知识

我们可以用新的JAVA关键字assert来书写断定语句。一条断定语句有以下两种合法的形式:

assert expression1;

assert expression1 : expression2;

expression1是一条被判断的布尔表达式,必须保证在程序执行过程中它的值一定是真;expression2是可选的,用于在expression1为假时,传递给抛出的异常AssertionError的构造器,因此expression2的类型必须是合法的AssertionError构造器的参数类型。以下是几条断定语句的例子:

assert 0 < value;

assert ref != null;

assert count == (oldCount + 1);

assert ref.m1(parm);

assert关键字后面的表达式一定要是boolean类型,否则编译时就会出错。

以下是使用断定语句的一个完整例子(见粗体语句行):

public class aClass {

public void aMethod( int value ) {

assert value = 0;

System.out.println( "OK" );

}

public static void main( String[] args ){

aClass foo = new aClass();

System.out.print( "aClass.aMethod( 1 ): " );

foo.aMethod( 1 );

System.out.print( "aClass.aMethod( -1 ): " );

foo.aMethod( -1 );

}

}

这段程序通过语句 assert value = 0; 来判断传入aMethod方法中的参数是否不小于0,如果传入一个负数,则会触发AssertionError的异常。

为了和J2SE 1.4 以前的程序兼容,在JDK1.4 中的javac 和 java 命令在默认情况下都是关闭assertion功能的,即不允许使用assert作为关键字,这就保证了如果你以前编写的程序中如果使用了assert作为变量名或是方法名,程序不必修改仍然可以运行。但需要注意的是,这些程序是无法使用JDK1.4 的javac进行重新编译的,只能使用JDK1.3或之前的版本编译。为了编译我们前面写的小程序,首先要使用符合J2SE 1.4 的编译器,同时还要使用几个命令行参数来使编译器启用assertion功能。

使用以下的命令来编译aClass.java:

javac -source 1.4 aClass.java

如果我们使用 ?java aClass 来运行这段程序,就会发现assertion语句实际上并未得到执行,和javac一样,java命令在默认情况下,关闭了assertion功能,因而会忽略assertion语句。如何启用assertion语句将在下一节讨论。

二、通过命令行控制assertion功能

assertion语句的一项最重要的特点是它可以被关闭,关闭的作用是这条代码虽然仍存在于程序当中,但程序运行时,JVM会忽略它的存在,不予执行,这样代码的运行速度不会由于assertion语句的存在而受到影响,如果代码执行过程中出现了问题,我们又可以启用assertion语句,帮助我们进行分析判断。默认情况下,这项功能是关闭的。(提示:本小节介绍的命令行参数都是针对SUN提供的JDK1.4而言,如果使用其他公司的JDK则未必会完全一样。)

JDK1.4 中,通过java命令的命令行选项 -ea (-enableassertions 的缩写)来启用。以下两个命令是等效的:

java -ea myPackage.myProgram

java -enableassertions myPackage.myProgram

同样,我们通过 -da (-disableassertions 的缩写)来关闭assertion功能:

java -da myPackage.myProgram

java -disableassertions myPackage.myProgram

assertion功能还可以针对特定的包(package)或类(class)分别启用和关闭。针对类时,使用完整的类名;针对包时,包名后面紧跟“...”:

java -ea:<class myPackage.myProgram

java -da:<package... myPackage.myProgram

在一个java命令中使用多项 -ea -da 参数时,后面的参数设定会覆盖前面参数的设定,比如我们可以默认启用所有的assertion功能,但针对特定的包却关闭此功能:

java -ea -da:<package... myPackage.myProgram

对于未命名的包(位于当前目录中)都属于默认包,可以使用以下的命令控制:

java -ea:... myPackage.myProgram

java -da:... myPackage.myProgram

对于随JVM安装时自己附带的所有系统类,可以分别使用 -esa(-enablesystemassertions)和-dsa(-disablesystemassertions)来控制assertion功能的启用和关闭。在表1.1中列出了控制assertion功能参数的所有用法。

表1 JDK1.4 中java命令和assertion功能有关的命令行参数

命令行参数 实例 含义

-ea Java -ea 启用除系统类外所有类的assertion

-da

Java -da 关闭除系统类外所有类的assertion

-ea:<classname

Java -ea:AssertionClass 启用AssertionClass类的assertion

-da:<classname

Java -da:AssertionClass 关闭AssertionClass类的assertion

-ea:<packagename Java -ea:pkg0... 启用pkg0包的assertion

-da:<packagename Java -da:pkg0... 关闭pkg0包的assertion

-esa

Java -esa 启用系统类中的assertion

-dsa

Java -dsa 关闭系统类中的assertion

至此,我们前面编写的小程序aClass可以用以下的任意命令运行:

java -ea aClass

java -ea:aClass aClass

java -ea:... aClass

运行结果如下:

aClass.aMethod( 1 ): OK

aClass.aMethod( -1 ): java.lang.AssertionError

at aClass.aMethod(aClass.java:3)

at aClass.main(aClass.java:12)

Exception in thread "main"

三、assertion命令行参数之间的继承关系

assertion功能的启用和关闭可以一直控制到每一个类,一个命令行可以容纳任意多个-ea -da 参数,这些参数之间是如何相互起作用的,基本上遵循两个原则:特定具体的设定优先于一般的设定,后面的?设定优先于前面的设定。我们看下面的例子:

// Base.java

package tmp;

public class Base{

public void m1( boolean test ){

assert test : "Assertion failed: test is " + test;

System.out.println( "OK" );

}

}

// Derived.java

//

package tmp.sub;

import tmp.Base;

public class Derived extends Base{

public void m2( boolean test ){

assert test : "Assertion failed: test is " + test;

System.out.println( "OK" );

}

public static void printAssertionError( AssertionError ae ){

StackTraceElement[] stackTraceElements = ae.getStackTrace();

StackTraceElement stackTraceElement = stackTraceElements[ 0 ];

System.err.println( "AssertionError" );

System.err.println( " class= " + stackTraceElement.getClassName() );

System.err.println( " method= " + stackTraceElement.getMethodName() );

System.err.println( " message= " + ae.getMessage() );

}

public static void main( String[] args ){

try{

Derived derived = new Derived();

System.out.print( "derived.m1( false ): " );

derived.m1( false );

System.out.print( "derived.m2( false ): " );

derived.m2( false );

}catch( AssertionError ae ){

printAssertionError( ae );

}

}

}

Base类和Derived

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有