邳州微网站开发,网站建设联雅,市场监督管理局,装饰设计有限公司经营范围[编辑本段]概述 Assert - 断言 编写代码时#xff0c;我们总是会做出一些假设#xff0c;断言就是用于在代码中捕捉这些假设#xff0c;可以将断言看作是异常处理的一种高级形式。断言表示为一些布尔表达式#xff0c;程序员相信在程序中的某个特定点该表达式值为真。可… [编辑本段]概述 Assert - 断言 编写代码时我们总是会做出一些假设断言就是用于在代码中捕捉这些假设可以将断言看作是异常处理的一种高级形式。断言表示为一些布尔表达式程序员相信在程序中的某个特定点该表达式值为真。可以在任何时候启用和禁用断言验证因此可以在测试时启用断言而在部署时禁用断言。同样程序投入运行后最终用户在遇到问题时可以重新起用断言。 使用断言可以创建更稳定品质更好且不易于出错的代码。当需要在一个值为FALSE时中断当前操作的话可以使用断言。单元测试必须使用断言Junit/JunitX。 除了类型检查和单元测试外断言还提供了一种确定各种特性是否在程序中得到维护的极好的方法。 使用断言使我们向按契约式设计更近了一步。 [编辑本段]常见的断言特性 前置条件断言代码执行之前必须具备的特性 后置条件断言代码执行之后必须具备的特性 前后不变断言代码执行前后不能变化的特性 [编辑本段]断言使用方式 断言可以有两种形式 1.assert Expression1 2.assert Expression1:Expression2 其中Expression1应该总是一个布尔值Expression2是断言失败时输出的失败消息的字符串。如果Expression1为假则抛出一个 AssertionError这是一个错误而不是一个异常也就是说是一个不可控制异常unchecked Exception),AssertionError由于是错误所以可以不捕获但不推荐这样做因为那样会使你的系统进入不稳定状态。 [编辑本段]启用断言 断言在默认情况下是关闭的要在编译时启用断言需要使用source1.4标记 既javac source1.4 Test.java ,在运行时启用断言需要使用 -ea参数 。要在系统类中启用和禁用断言可以使用 -esa 和 -dsa参数。 例如 public class AssertExampleOne{ public AssertExampleOne(){} public static void main(String args[]){ int x10; System.out.println(Testing Assertion that x100); assert x100:Out assertion failed!; System.out.println(Test passed!); } } 如果编译时未加 -source1.4,则编译通不过 在执行时未加 -ea 时输出为 Testing Assertion that x100 Test passed jre忽略了断言的就代码而使用了该参数就会输出为 Testing Assertion that x100 Exception in thread main java.lang.AssertionError: Out assertion failed! at AssertExampleOne.main(AssertExampleOne.java:6) 断言的副作用 由于程序员的问题断言的使用可能会带来副作用 例如 boolean isEnablefalse; //... assert isEnabletrue; 这个断言的副作用是因为它修改了程序中变量的值并且未抛出错误这样的错误如果不细心的检查是很难发现的。但是同时我们可以根据以上的副作用得到一个有用的特性根据它来测试断言是否打开。 public class AssertExampleTwo{ public static void main(String args[]){ boolean isEnablefalse; //... assert isEnabletrue; if(isEnablefalse){ throw new RuntimeException(Assertion shoule be enable!); } } } [编辑本段]何时需要使用断言 1.可以在预计正常情况下程序不会到达的地方放置断言 assert false 2.断言可以用于检查传递给私有方法的参数。对于公有方法因为是提供给外部的接口所以必须在方法中有相应的参数检验才能保证代码的健壮性 3.使用断言测试方法执行的前置条件和后置条件 4.使用断言检查类的不变状态确保任何情况下某个变量的状态必须满足。如age属性应大于0小于某个合适值 [编辑本段]什么地方不要使用断言 断言语句不是永远会执行可以屏蔽也可以启用 因此 1.不要使用断言作为公共方法的参数检查公共方法的参数永远都要执行 2.断言语句不可以有任何边界效应不要使用断言语句去修改变量和改变方法的返回值 [编辑本段]C里面的函数 函数名: assert 功 能: 测试一个条件并可能使程序终止 用 法: void assert(int test); 程序例: #include assert.h #include stdio.h #include stdlib.h struct ITEM { int key; int value; }; /* add item to list, make sure list is not null */ void additem(struct ITEM *itemptr) { assert(itemptr ! NULL); /* add item to list */ } int main(void) { additem(NULL); return 0; } assert() 函数用法 assert宏的原型定义在assert.h中其作用是如果它的条件返回错误则终止程序执行原型定义 #include assert.h void assert( int expression ); assert的作用是现计算表达式 expression 如果其值为假即为0那么它先向stderr打印一条出错信息 然后通过调用 abort 来终止程序运行。 请看下面的程序清单badptr.c #include stdio.h #include assert.h #include stdlib.h int main( void ) { FILE *fp; fp fopen( test.txt, w );//以可写的方式打开一个文件如果不存在就创建一个同名文件 assert( fp ); //所以这里不会出错 fclose( fp ); fp fopen( noexitfile.txt, r );//以只读的方式打开一个文件如果不存在就打开文件失败 assert( fp ); //所以这里出错 fclose( fp ); //程序永远都执行不到这里来 return 0; } [rootlocalhost error_process]# gcc badptr.c [rootlocalhost error_process]# ./a.out a.out: badptr.c:14: main: Assertion fp failed. 已放弃 使用assert的缺点是频繁的调用会极大的影响程序的性能增加额外的开销。 在调试结束后可以通过在包含#include assert.h的语句之前插入 #define NDEBUG 来禁用assert调用示例代码如下 #include stdio.h #define NDEBUG #include assert.h 用法总结与注意事项 1)在函数开始处检验传入参数的合法性 如: int resetBufferSize(int nNewSize) { //功能:改变缓冲区大小, //参数:nNewSize 缓冲区新长度 //返回值:缓冲区当前长度 //说明:保持原信息内容不变 nNewSize0表示清除缓冲区 assert(nNewSize 0); assert(nNewSize MAX_BUFFER_SIZE); ... } 2)每个assert只检验一个条件,因为同时检验多个条件时,如果断言失败,无法直观的判断是哪个条件失败 不好: assert(nOffset0 nOffsetnSizem_nInfomationSize); 好: assert(nOffset 0); assert(nOffsetnSize m_nInfomationSize); 3)不能使用改变环境的语句,因为assert只在DEBUG个生效,如果这么做,会使用程序在真正运行时遇到问题 错误: assert(i 100) 这是因为如果出错比如在执行之前i100,那么这条语句就不会执行那么i这条命令就没有执行。 正确: assert(i 100) i; 4)assert和后面的语句应空一行,以形成逻辑和视觉上的一致感 5)有的地方,assert不能代替条件过滤 注意当对于浮点数 #includeassert.h // float pi3.14; // assert(pi3.14); // float pi3.14f; assert (pi3.14f); --------------------------------------------------------- 在switch语句中总是要有default子句来显示信息(Assert)。 int number SomeMethod(); switch(number) { case 1: Trace.WriteLine(Case 1:); break; case 2: Trace.WriteLine(Case 2:); break; default : Debug.Assert(false); break; } 转载于:https://blog.51cto.com/no001/354220