《疯狂Java讲义精粹》读书笔记15 ------ 异常处理(一)
===========《疯狂Java讲义精粹》读书笔记15 ------ 异常处理(一)==========
一门成熟的编程语言应该包含异常处理机制。
没有人能够保证自己写的程序永远不会出错,对于一个程序设计人员来说应该尽可能地与之可能发生的情况,尽可能地保证程序在所有糟糕的情形下都可以运行。Java的异常处理机制具有极好的容错性,可以让程序更加的健壮。当程序出现意外情形的时候,系统会自动生成一个Exception对象来通知程序,从而将“业务功能实现代码”和“错误处理代码”分离,提供更好的可读性。
下面是异常处理的几个关键字:
· try 放置可能发生错误的代码
· catch 用于处理某种错误
· finally 回收try块里面打开的物理资源,总会执行
· throws 用于声明某个方法可能抛出异常
· throw 抛出一个具体的异常对象
一、使用try-catch捕获异常
使用格式:
try{ //业务实现代码 ...... } catch (Exception e) { //提示异常 //处理异常 }
当try块里面的业务逻辑代码出现异常的时候,系统会自动生成一个异常对象,该异常对象提交给Java运行环境,这个过程称为抛出异常。当java 运行环境收到异常对象时,会自动寻找能处理该异常对象的catch块。如果找到合适的catch块,则把该异常对象交给catch快处理,这个过程称为捕获异常。
如果Java运行时环境找不到相应的catch块,则运行时环境终止,Java程序也将退出。
· try块后可以有多个catch块,针对不同的异常类型提供不同的异常处理方式
· try和catch后面的{}不可以省略,即使只有一行代码。
· 如果try块被执行一次,则try块后只有一个catch将会被执行。
· 从Java7开始,一个catch可以捕获多种类型的异常(用|分开)。
· 捕获父类异常的catch块必须位于捕获子类异常的catch块后面
· 异常处理可以嵌套
二、Java提供了丰富的异常类,这些异常类有严格的继承关系:
从上图可以看出,Java把所有的非正常情况分为两类:Exception和Error,他们都继承Throwable父类。
Error 错误:一般是指与虚拟机相关的问题,如系统崩溃、虚拟机错误、动态链接失败吧、等,这种错误无法恢复和捕获,将导致应用程序中断。
三、访问异常信息:
· getMessage():返回该异常的详细描述字符串
· printDtackTrace():将该异常的跟踪栈信息输出到标准错误输出
· printStackTrace(PrintStream s):将该异常的跟踪栈信息输出到指定输出流
下面示例演示了程序如何访问异常信息:
import java.io.FileInputStream; import java.io.IOException; public class TestExceptionMsg { public static void main(String[] args) { try{ FileInputStream fis = new FileInputStream("Exception.txt"); } catch (IOException e) { System.out.println(e.getMessage()); e.printStackTrace(); } } }
异常信息:
四、使用fanally回收资源
有时候,程序在try块里打开了一些物理资源(例如数据库连接,网络连接和磁盘你文件等),这些物理资源都必须显示地回收(Java的垃圾回收机制不会回收任何物理资源,只回收堆内存中对象所占用的内存)。
· 不管try块或catch块是否执行,甚至在try-catch里面执行了return语句,finally块总会执行。
· finally块必须位于所有catch块之后
如下面的程序
import java.io.FileInputStream; import java.io.IOException; public class TestFnally { public static void main(String[] args) { FileInputStream fis = null; try { fis = new FileInputStream("a.txt"); } catch (IOException e) { System.out.println(e.getMessage()); //使用return 语句强制方法返回 return; //使用exit(1)退出虚拟机】 //System.exit(1); } finally { //关闭磁盘文件 if(fis != null){ try { fis.close(); } catch (IOException e2) { e2.printStackTrace(); } } System.out.println("执行finally 块中的资源回收!"); } } }
输出:
a.txt (系统找不到指定的文件。)
执行finally 块中的资源回收!
从输出结果可以知道:
· 即使方法中有return语句,finally中的语句依然会执行
· 把return注释掉 调用System.exit(1);finally块中的语句就不会执行了。
注意:不要在finally块中使用如return,throw等导致方法终止的语句,否则将导致try块,catch块中的return、throw语句失效。
看下面的程序:
public class FinallyFlowTest { public static void main(String[] args) throws Exception { boolean a = test(); //将会输出false System.out.println(a); } public static boolean test(){ try { //因为finally中包含了return 语句,所以下面的return语句失去作用 return true; } finally { return false; } } }