[core.java基础教程]_杨帆_08.java面向对象编程-异常与断言

killerdongbo

贡献于2013-05-12

字数:0 关键词: Java开发

http://gzyangfan.spaces.live.com/blog/ gzyangfan@gmail.com  定义异常  使用 try、catch 和 finally 语句  描述异常分类  识别普通异常  开发程序处理您自己的异常  使用断言  区分适当和不适当的断言使用  在运行时启用断言 学习目标 gzyangfan@gmail.com 不要指望你的程序永远不会出错 异常 gzyangfan@gmail.com  异常处理非预期情况 — 非法的参数、网络故障或文 件没有找到  断言文档和测试程序的假设 — 这永远不能为负数  断言测试可以在运行时从代码中完全删除,所以代码 的运行速度根本不会慢下来。 异常和断言 gzyangfan@gmail.com  正确的程序中很容易发生的情况称为可查异常。 ◦ 这些异常用 Exception 类表示。  通常视为致命错误的严重问题或程序可能存在错误的 情况称为不可查异常。 ◦ 致命的情况由 Error 类表示。 ◦ 可能的错误由 RuntimeException 类表示。  API 文档显示可从一个方法引发的可查异常。 异常 gzyangfan@gmail.com  Error:  RuntimeException: 异常示例 public class ErrorShow { public static int callMe(int i) { return callMe(i++); } public static void main(String[] args) { ErrorShow.callMe(1); } } public class RuntimeExceptionShow { public static void main(String[] args) { System.out.println(args[0]); } } gzyangfan@gmail.com  Exception: 异常示例 public class ExceptionShow { public static void main(String[] args) { try { Class clz = Class.forName( "frank.java.chapter08.UnknowClass"); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } gzyangfan@gmail.com Throwable Error VirtualMachineError StackOverflowError …… OutOfMemoryError…… AssertionError Exception RuntimeException NullPointerException …… IllegalArgumentException…… IOException 异常体系 gzyangfan@gmail.com  构造方法 ◦ Throwable() ◦ Throwable(String message) ◦ Throwable(String message, Throwable cause) ◦ Throwable(Throwable cause)  常用方法 ◦ getCause() ◦ getMessage() ◦ getStackTrace() ◦ printStackTrace() ◦ …… Throwable 常用方法 gzyangfan@gmail.com  Java程序在执行中如出现异常,会自动创建一个异常 类(Throwable)实例,该实例将被提交给Java运行时 系统,这个过程称为抛出(throw)异常。  当Java运行时系统接收到异常时,会寻找能处理这一 异常的代码并把当前异常交给其处理,这一过程称为 捕获(catch)异常。  如果Java运行时系统找不到可以捕获异常的方法,异 常直接传递到 main 方法,相应的Java程序也将退出。 Java异常处理机制 gzyangfan@gmail.com  示例一: try-catch 语句 public static void main(String[] args) { String[] strings = {"32", "one", "10.8", "45"}; int sum = 0; try { for (String s : strings) { sum += Integer.parseInt(s); } System.out.println("Sum : " + sum); } catch (NumberFormatException e) { System.out.println(e.getMessage()); } } gzyangfan@gmail.com  示例二: try-catch 语句 public static void main(String[] args) { String[] strings = { "32", "one", "10.8", "45" }; int sum = 0; for (String s : strings) { try { sum += Integer.parseInt(s); } catch (NumberFormatException e) { System.out.println(e.getMessage()); } } System.out.println("Sum : " + sum); } gzyangfan@gmail.com  try-catch 语句可以使用多重 catch 子句: 多重 catch 语句 public static void main(String[] args) { int key = (int) (Math.random() * 3 + 1); try { switch (key) { case 1: throw new IllegalArgumentException(); case 2: throw new SecurityException(); case 3: throw new IOException(); } } catch (IllegalArgumentException e) { …… } catch (SecurityException e) { …… } catch (IOException e) { …… } } gzyangfan@gmail.com  如果一个异常在当前 try-catch 块中没有处理,则它 将抛向此方法的调用方。  如果该异常回到 main 方法,而且也没有被处理,则 程序将会异常地终止。 调用堆栈机制 gzyangfan@gmail.com  finally 子句定义始终执行的代码块。 finally 子句 public static void main(String[] args) { try { int i = (int) (Math.random() * 10); if (i % 2 == 0) { System.out.println("准备抛异常!"); throw new RuntimeException("刻意抛出的异常 "); } else { System.out.println("这次不打算抛异常了!"); } } catch (RuntimeException e) { System.out.println("捕获到异常了!"); } finally { System.out.println("最终的收尾工作!"); } } gzyangfan@gmail.com  try ◦ 可能出现异常的代码都应放在 try 代码块中。 ◦ 当异常出现后程序控制就转交给 catch 语句块。  catch ◦ catch 语句块按声明的异常进行异常捕获。 ◦ 一个 try 块可以和多个 catch 块配合以处理多个异常。 ◦ 多捕获时要按照从小到大的顺序进行异常声明。  finally ◦ 无论是否出现异常,finally 代码块最终都将执行。 ◦ finally 经常用于资源的释放工作。 ◦ 当代码中使用 System.exit() 进行程序终止,finally 块会 无法被执行。 try-catch-finally 语句块说明 gzyangfan@gmail.com  可通过继承 Exception 或它的子类来定制自己的异 常体系。  对于代码失误(粗心大意引起的,可修复的)引起的异 常,应定义为运行时异常。  对于由运行环境引发的,代码无法避免的异常,应定 义为可查异常。  一个系统或一个复杂的模块可通过定义自己的异常体 系来化简客户代码的处理。  异常可用来传递信息,但不应依赖于异常进行信息传 递,这样会加大客户代码的复杂度。  可在 catch 内将捕获的异常重新包装再抛出。 自定义异常 gzyangfan@gmail.com 自定义异常示例  Spring DAO 模块的异常体系 gzyangfan@gmail.com  按如下方式使用处理或声明规则: ◦ 通过使用 try-catch-finally 块处理异常。 ◦ 使用 throws 子句声明代码会产生异常。 void trouble() throws IOException { ... } void trouble() throws IOException, MyException { ... }  其他规则 ◦ 不需要声明运行时异常或错误。 ◦ 可以选择处理运行时异常。 处理或声明规则 gzyangfan@gmail.com  覆盖方法可以引发: ◦ 没有异常 ◦ 由覆盖方法引发的一个或多个异常 ◦ 由覆盖方法引发的一个或多个异常的子类  覆盖方法不能引发: ◦ 覆盖方法没有引发的其他异常 ◦ 由覆盖方法引发的异常的超类 方法覆盖与异常 gzyangfan@gmail.com  try-catch-finally 也可以嵌套 try-catch-finally 实现 更精确的异常控制。  finally 块中不能修改返回值,但可以修改返回对象的 内容。  如果 finally 块中有返回语句,finally 的返回内容会 覆盖 try 或 catch 块中的返回内容。 其他异常话题 gzyangfan@gmail.com 用断言可以创建更稳定,品质更好且易于除错的代码。 断言 gzyangfan@gmail.com  断言的语法是: ◦ assert ; ◦ assert : ;  如果 的值为 false,则引发 AssertionError。  第二个参数被转换成字符串并用作 AssertionError 消息中的描述文本。 断言 gzyangfan@gmail.com  如果禁用断言检查,则代码的运行速度与没有检查时 的速度一样快。  检查可以使用以下命令启用断言: java -enableassertions MyProgram 或: java -ea MyProgram  断言检查可以在类、包和包的层次结构基中控制,请 参见: http://java.sun.com/j2se/1.5.0/docs/guide/langu age/assert.html 控制断言运行时求值 gzyangfan@gmail.com  断言也是一种异常,也可以被捕获 断言使用示例 public static void main(String[] args) { assert args.length > 0 : "参数不能为空"; System.out.println("程序正常结束"); } public static void main(String[] args) { try { assert args.length > 0 : "参数不能为空"; System.out.println("程序正常结束"); } catch (AssertionError e) { System.out.println("捕获到了"); e.printStackTrace(System.err); } } gzyangfan@gmail.com  使用断言记录并检验假设和某一方法的内部逻辑: ◦ 内在不变式 ◦ 控制流不变式 ◦ 后置条件和类不变式  断言的不当使用 ◦ 不要使用断言来检查公有方法的参数。 ◦ 不要在断言检查中使用可引起副作用的方法。 断言的建议使用 gzyangfan@gmail.com  示例: 内在不变式 /** * 判断一个数是否是正数 * @param number 正数或负数 * @return 正数:true 负数:false */ public static boolean isPositive(int number) { if (number > 0) { return true; } else { assert number != 0 : "0不在该方法的处理范围内 "; return false; } } gzyangfan@gmail.com  示例: 控制流不变式 /** * 考试成绩转换为评分等级 * @param number 考试成绩 * @return A / B / C / D */ public static Grade toGrade(float number) { if (number > 85) { return Grade.A; } else if (number > 75) { return Grade.B; } else if (number > 60) { return Grade.C; } else if (number >= 0) { return Grade.D; } assert false : "不应该出现负数的成绩"; return null; } gzyangfan@gmail.com  示例: 后置条件和类不变式 private int size = 0; private Object[] contents = new Object[10]; public void push(Object obj) { if (contents.length == size) contents = Arrays.copyOf(contents, contents.length * 2); contents[size++] = obj; // 后置条件断言,检查类内部逻辑的正确性 assert contents.length >= size; } public Object pop() { int idx = size; if (idx == 0) throw new RuntimeException("栈为空"); Object result = contents[--size]; contents[size] = null; // 后置条件断言,检查类内部逻辑的正确性 assert size == idx - 1; return result; }

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 2 金币 [ 分享文档获得金币 ] 0 人已下载

下载文档

相关文档