一、异常处理的优势:
异常处理最根本的优势就是检测错误(由被调用的方法完成)从处理错误(由调用方法完成)中分离出来。这样,可以使程序更易读懂和修改。
二、异常的类型:
1、java异常框架:
2、异常分为三种类型:
系统错误(System Error,属于Unchecked Exception)、非运行时异常(属于Checked Exception)、运行时异常(属于Unchecked Exception)。除了Error和Runtime Exception都是Checked Exception,也就是必须检查的异常,编写代码的时候编译系统会有提示,必须强制捕捉异常,否则编译不能通过。免检异常可能会在程序的任何地方出现,为避免过多地使用try-catch块,java语言允许编写代码捕获或者声明免检异常。
API中的描述:
Throwable
类是 Java 语言中所有错误或异常的超类。只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java
throw
语句抛出。类似地,只有此类或其子类之一才可以是
catch
子句中的参数类型。
三、关于异常处理的更多知识:
1、声明异常:
格式:public void myMethor( ) throws IOException……
注意:如果方法没有在父类声明异常,那么就不能在子类中对其进行覆盖来声明异常。重写方法需要抛出与原方法所抛出异常类型一致异常或不抛出异常。子类抛出的异常类型不能比父类抛出的异常类型更宽泛
。
2、抛出异常:
格式:throw new IllegalArgumentException("Wrong Argument");
注意:声明异常是关键字throws,抛出异常是关键字Throw。
3、捕获异常:
try-catch-finally 的执行顺序。
如果没有发现异常处理器,Java会退出这个方法并把异常传递给调用这个方法的方法,继续同样的过程来查找处理器。如果在调用的方法链中找不到处理器,程序就会终止并且在控制台打印出错误信息。
注意:从一个通用父类可以派生出各种异常类,如果一个catch块可以捕获一个父类的异常对象,它就能捕获那个父类的所有子类的异常对象。
注意:java强迫程序员处理必检异常,如果方法中声明了一个必检异常, 就必须在try-catch块中调用它,或者在调用方法中声明要抛出的异常。
举例:
public void fun( int a) throws IllegalArgumentException{
if(a >=0)
System.out.print(a);
else
throw new IllegalArgumentException("message");
}
上面的例子即使删除异常声明,编译仍然会通过,因为IllegalArgumentException是RuntimeException的子类,不管是否在方法头声明,每个方法都会抛出RuntimeException异常(免检异常)。
4、从异常中获取信息:
printStackTrace():java.lang.ArrayIndexOutOfBoundsException:5
at TestException.sum(TestException.java.24)
getMessage():5
toString():java.lang.ArrayIndexOutOfBoundsException:5
getStackTrace(): Track Info Obtained from getStackTrace
methor sum(TestException : 24)
5、何时使用异常:
异常处理最根本的优势就是检测错误(由被调用的方法完成)从处理错误(由调用方法完成)中分离出来。这样,可以使程序更易读懂和修改。但是,应该注意,由于异常处理需要初始化新的异常对象,需要从调用栈中返回,而且还需要沿着方法调用链来传播异常以便找到它的异常处理器,所以,异常处理通常需要更多的时间和资源。
当必须处理不可预料的错误状况时才应该使用它,不要用try-catch处理简单的,可预料的情况。
不管怎么样,一定呀把握住,不要把异常处理用做简单的逻辑测试。
使用异常的原则。
6、重新抛出异常:
7、链式异常:
8、创建自定义异常:
9、习题:
- 异常的对象从哪里来呢? 有两个来源,一是Java运行时环境自动抛出系统生成的异常,而不管你是否愿意捕获和处理,它总要被抛出。二是程序员自己抛出的异常,这个异常可以是程序员自己定义的,也可以是Java语言中定义的,用throw 关键字抛出异常,这种异常常用来向调用者汇报异常的一些信息。
- 发生异常后,java虚拟机会做什么? 当一个方法抛出一个异常时,Java虚拟机就是用异常表去判断如何处理这个异常。如果虚拟机找到了一个匹 配的catch,他就会将控制权交给catch语句。如果没有找到匹配的catch,方法就会异常返回,然后再调用的方法中继续这个过程。
try{
statement1;
statement2;
statement3;
}catch(Exception1 ex1){
}catch(Exception2 ex2){
}
statement4;
回答以下问题:假设statment2引起一个异常。
- 会执行statement3吗? 不会。
- 如果异常未必捕获,会执行statement4吗? 不会。
- 如果在catch中捕获了异常,会执行statement4吗? 会。
- 如果异常被传递给了调用者,会执行statement4 吗? 不会。