在学习代理模式的时候,编写动态生成代理类.java文件时,用try{}catch(){}捕获异常发现catch(Exception e)报错,得换成catch(Throwable e),然后又查了查两者的区别,在文章最后附上。
这里还是要码一码throws、throw和try catch三者的关系,关键让自己加深印象。
先介绍一下try catch finally的基本运行流程:
在try语句块中,放入的是你感觉会出现错误的代码,在catch语句块中放入的就是如果try语句块中的代码抛出异常之后所要执行的代码。
try{ 代码1; 代码2; }catch(Exception e){ 代码3; }finally{ 代码4; } 代码5
1. 正常执行,代码1没有抛出异常,程序的执行顺序就是代码1,代码2,代码4,代码5,。因为没有抛出异常所以跳过了catch语句块。
2. 代码1抛出异常,被catch语句块捕获,而catch语句块中的代码没有抛出新的异常,这样的执行顺序就是代码1,代码3,代码4,代码5。
3. 代码1抛出异常,catch语句块捕获并抛出新的异常,这时候的执行顺序应该为代码1,代码3,代码4,并抛出异常。不执行代码5。
4. 代码1抛出异常,而catch语句块没有与之匹配的异常,那么它的执行顺序就是代码1,代码4.并将异常返回给方法调用者。不执行代码5。
小结:try中如果某行代码抛出异常,不再执行try中其他代码。并向catch语句块抛出异常。catch语句块捕获处理异常,则是为了能够让代码能够顺利运行下去,不会因为try语句块中的异常而终止整个程序。finally语句块则是必定要执行的语句块,不论是否会抛出异常,一定会被执行。若catch语句块与try语句块所抛出的异常无法匹配或抛出新异常,finally之后的代码不执行。
throws、throw和try catch解释
1.throw 是语句抛出一个异常,如throw new Exception();他不处理异常,直接抛出异常;
1.throws是表明方法抛出异常,需要调用者来处理,如果不想处理就一直向外抛,最后会有jvm来处理;
2.try catch 是自己来捕获别人抛出的异常,然后在catch里面去处理。
使用:
1. 调用一个会throws exception的方法(在方法定义的时候可以用throws实现)时,需要把这个方法调用放在try里,然后用catch破获这个exception,做相应的处理。
2. try....catch是为捕获别人的exception用的,而throw是自己抛出exception让别人去捕获的。
3. throw要么和try-catch-finally语句配套使用,要么与throws配套使用。但throws可以单独使用,然后再由处理异常的方法捕获。
例如下图
在可能会抛出异常的方法使用throws
将调用该方法的代码放入try中由catch捕获并处理,这里使用printStackTrace()方法,在命令行打印异常信息在程序中出错的位置及原因。
运行结果如下,发现并没有抛出异常(没执行catch),但是调用使用throws的方法一定要放在try中
去除throw代码的注释
再次运行,则会在命令行窗口打印try中第一次抛出异常的位置及原因(try中抛出异常的行后的代码不再执行)
由于抛出的异常和catch的异常匹配,则能继续执行try catch以外的代码。
附Throwable、 Error、Exception关系
Error类和Exception类的父类都是throwable类,他们的区别是:
Error类一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢等。对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和和预防,遇到这样的错误,建议让程序终止。
Exception类表示程序可以处理的异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行,而不应该随意终止异常。
Exception类又分为运行时异常(Runtime Exception)和受检查的异常(Checked Exception ),运行时异常;ArithmaticException,IllegalArgumentException,编译能通过,但是一运行就终止了,程序不会处理运行时异常,出现这类异常,程序会终止。而受检查的异常,要么用try。。。catch捕获,要么用throws字句声明抛出,交给它的父类处理,否则编译不会通过。
Exception 子类下面的另一部分子类对应于Java程序中的非运行时异常的处理(在下图中将它们直接属于Exception了),这些异常也称为显式异常。它们都是在程序中用语句抛出、并且也是用语句进行捕获的,比如,文件没找到引起的异常、类没找到引起的异常等。
一些主要子类对应的异常处理功能简要说明如下:
ArithmeticException——由于除数为0引起的异常;
ArrayStoreException——由于数组存储空间不够引起的异常;
ClassCastException—一当把一个对象归为某个类,但实际上此对象并不是由这个类 创建的,也不是其子类创建的,则会引起异常;
IllegalMonitorStateException——监控器状态出错引起的异常;
NegativeArraySizeException—一数组长度是负数,则产生异常;
NullPointerException—一程序试图访问一个空的数组中的元素或访问空的对象中的 方法或变量时产生异常;
OutofMemoryException——用new语句创建对象时,如系统无法为其分配内存空 间则产生异常;
SecurityException——由于访问了不应访问的指针,使安全性出问题而引起异常;
IndexOutOfBoundsExcention——由于数组下标越界或字符串访问越界引起异常;
IOException——由于文件未找到、未打开或者I/O操作不能进行而引起异常;
ClassNotFoundException——未找到指定名字的类或接口引起异常;
CloneNotSupportedException——一程序中的一个对象引用Object类的clone方法,但 此对象并没有连接Cloneable接口,从而引起异常;
InterruptedException—一当一个线程处于等待状态时,另一个线程中断此线程,从 而引起异常,有关线程的内容,将在下一章讲述;
NoSuchMethodException一所调用的方法未找到,引起异常;
Illega1AccessExcePtion—一试图访问一个非public方法;
StringIndexOutOfBoundsException——访问字符串序号越界,引起异常;
ArrayIdexOutOfBoundsException—一访问数组元素下标越界,引起异常;
NumberFormatException——字符的UTF代码数据格式有错引起异常;
IllegalThreadException—一线程调用某个方法而所处状态不适当,引起异常;
FileNotFoundException——未找到指定文件引起异常;
EOFException——未完成输入操作即遇文件结束引起异常。
看到一个比较有意思的关于返回值验证try catch finally执行顺序的帖子:
https://blog.csdn.net/wangqingbo0829/article/details/52458283为转载位置
/** * @author qing * * Try……catch……finally中return的测试 */ public class TryTest { /** * 主要方法 */ public static void main(String[] args) { // 调用 测试方法 String result = get(); // 打印 测试方法返回的结果 System.out.println(result); } @SuppressWarnings({ "finally", "unused" }) public static String get(){ int value = 0; try { System.out.println("try……"); //等式1/0 :分母为0 的明显错误 ——制造错误(用于抛异常) int result = 1 / value; return "111"; } catch (Exception e) { System.out.println("catch……"); return "444"; } finally { System.out.println("finally……"); return "333"; } // return "222"; }
运行结果:
经过测试:
(1)在通过编译器的检查后,如果finally中有return,则以finally中的return为准,其他的都将失效,return之前的代码都有效。
(2)第37行的return “222” 于catch、finally中的任何一个return互斥。也就是说,在catch、finally中其中一个地方存在return,编译器就能检查,已符合方法的返回要求。
(3)catch和finally中,可同时存在return,编译能通过。但程序以finally中的return “333”为准,不会理睬catch中的return “444”,catch中return之前的代码仍然生效。
示例2. (这种情况就比较好理解了)
程序中try内部没有异常的情况下,若有finally,且finally中没有return。若在try中遇到return,则先跳去执行finally中的代码,在回来执行try中return。
package threadproject; /** * @author qing * * Try……catch……finally中return的测试 */ public class TryTest { /** * 主要方法 */ public static void main(String[] args) { // 调用 测试方法 String result = get(); // 打印 测试方法返回的结果 System.out.println(result); } public static String get(){ try { System.out.println("try……"); return "111"; } catch (Exception e) { System.out.println("catch……"); } finally { System.out.println("finally……"); } return "222"; } }
运行结果为:
上面的程序不会执行 try……Catch……finally之外的return,即打印的是“111”,而不打印“222”。