------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
异常就是在程序的运行过程中所发生的意外事件,它中断指令的正常执行。Java中提供了一种独特的处理异常的机制,通过异常来处理程序设计中出现的错误。
一、异常类的分类与层次:
在jdk中,每个包中都定义了异常类,而所有的异常类都直接或间接地继承于java.lang.Throwable类。当Java程序遇到不可预料的错误时,会实例化一个从Throwable类继承的对象。java中的异常类可分为两大类:
Error: 错误Error类指的是系统错误或运行环境出现的错误,这些错误一般是很严重的错误,即使捕捉到也无法处理,由Java虚拟机生成并抛出,包括系统崩溃、动态链接失败、虚拟机错误等,在Java程序中不做处理。
Exception: 异常Exception类则是指一些可以被捕获且可能恢复的异常情况,是一般程序中可预知的问题。对于异常可分为两类:
(1)运行时异常:程序中可以不做处理,直接由运行时系统来处理。
(2)编译时异常:在程序中必须对其进行处理,否则编译器会指出错误。
Exception类:
Exception类的构造方法
(1)Exception();//没有指定的消息串,直接构造一个Exception。
(2)Exception(String exp);//根据参数提供的消息串,创建一个Exception。
例:
Exception myExp=new Exception(“异常!”);
Exception类的常用函数
(1) String getMessage() ;//返回该异常所存储的描述性字符串;
(2) String toString();//返回异常对象的详细信息,包含该类名和指出所发生问题的描述性消息的字符串;
(3) void printStackTrace();//将异常发生的路径,即引起异常的方法调用嵌套序列打印到标准错误流。
例如:
System.out.println(myExp.getMessage());
此语句可以将异常对象myExp的异常信息描述打印输出,在屏幕上显示“异常!”。
自定义异常类:
在程序中,可以创建自定义的异常类。用户自定义的异常类都要直接或间接地继承Exception类。按照下面的方法自定义一个异常类:
(1)创建一个继承Exception类或者其它已存在的异常类的子类。
(2)在该类中创建一个默认的无参数构造方法,该构造方法以适当的错误消息作为输入,调用它的超类的构造方法。
(3)再增加一个带字符串参数的构造方法,该构造方法以适当的错误消息作为输入(还包括输入的字符串)来调用其超类相应的构造方法。
例:
定义一个继承于Exception类的用户自定义异常类,语句如下:
class MyException extends Exception{
MyException(){ super(“数据错误!”);}
MyException(String exp){super(exp); }
}
二、异常的处理机制:
每当Java程序运行过程中发生一个可识别的运行错误时,即该错误有一个异常类与之相对应时,系统都会产生一个相应的该异常类的对象,即产生一个异常。一旦一个异常对象产生了,系统中就一定有相应的机制来处理它,确保不会产生死机、死循环或其他对操作系统的损害,从而保证了整个程序运行的安全性。这就是Java的异常处理机制。
Java中处理异常有两种方式:
(1)捕获异常,就地解决,并使程序继续执行。
(2)声明抛出异常也就是将异常向外转移,即将异常抛出方法之外,由调用该方法的环境去处理。
捕获异常:
当Java运行时系统得到一个异常对象时,它将会沿着方法的调用栈逐层回溯,寻找处理这一异常的代码。找到能够处理这种类型的异常的方法后,运行时系统把当前异常对象交给这个方法进行处理,这一过程称为捕获(catch)异常。这是积极的异常处理机制。如果Java运行时系统找不到可以捕获异常的方法,则运行时系统将终止,相应的Java程序也将退出。
捕获异常是通过try-catch-finally语句实现的,格式如下:
try{
//接受监视的程序块,在此区域内发生的异常,由catch中指定的程序处理
}catch(要处理的异常种类和标识符){
//处理异常
}catch(要处理的异常种类和标识符){
//处理异常
}
…
}finally{
//最终处理
}
try:捕获异常的第一步是用try{可能抛出异常的语句}选定捕获异常。
catch:可以伴随一个或多个catch语句,用于处理try代码块中所生成的异常事件。catch语句只需要一个形式参数指明它所能够捕获的异常类型,这个类必须是Throwable的子类,运行时系统通过参数值把被抛弃的异常对象传递给catch块。catch 语句的顺序 捕获异常的顺序和catch语句的顺序有关,当捕获到一个异常时,剩下的catch语句就不再进行匹配。因此,在安排catch语句的顺序时,首先应该捕获最特殊的异常,然后再逐渐一般化。也就是一般先安排子类,再安排父类。在catch块中是对异常对象进行处理的代码,与访问其它对象一样,可以访问一个异常对象的变量或调用它的方法。getMessage( )是类Throwable所提供的方法,用来得到有关异常事件的信息,类Throwable还提供了方法printStackTrace( )用来跟踪异常事件发生时执行堆栈的内容。
finally:捕获异常的最后一步是通过finally语句为异常处理提供一个统一的出口,使得在控制流转到程序的其它部分以前,能够对程序的状态作统一的管理。不论在try代码块中是否发生了异常事件,finally块中的语句都会被执行。
例:
public class TryCatchDemo{
public static void main(String args[]) {
int a,b,c;
try {
a=100;
b=Integer.parseInt(args[0]);//把命令行输入的字符转换成整数
c=a/b;
System.out.println("c="+c);
System.out.println("没有异常!");
}catch(ArrayIndexOutOfBoundsException e) { //数组下标越界异常
System.out.println("捕获异常:"+e.getMessage());
e.printStackTrace();
}catch(ArithmeticException e) { //处理算术运算异常
System.out.println("捕获异常:"+e.getMessage());
e.printStackTrace();
}finally{
System.out.println("执行完毕!");
}
}
}
声明抛出异常:
在Java程序的执行过程中,如果出现了异常事件,就会生成一个异常对象。生成的异常对象将传递给Java运行时系统,这一异常的产生和提交过程称为抛出异常。
抛出异常就是产生异常对象的过程,首先要生成异常对象,异常或者由虚拟机生成,或者由某些类的实例生成,也可以在程序中生成。在方法中,抛出异常对象是通过throw语句实现的。
例:
IOException e=new IOException();
throw e ;
注:可以抛出的异常必须是Throwable或其子类的实例。
throw new String("want to throw"); (语法错误)
如果一个方法并不知道如何处理所出现的异常,则可在方法声明时,声明抛出异常。使得异常对象可以从调用栈向后传播,直到有合适的方法捕获它为止。这是一种消极的异常处理机制。也就是说抛出异常的方法和处理异常的方法不是同一个方法时,则需声明抛出异常。用方法声明中的throws子句指明。
例:public int read () throws IOException{
...
}
throws子句中同时可以指明多个异常,之间由逗号隔开。
例:
public static void main(String args[]) throws IOException,IndexOutOfBoundsException {
…
}
注:
(1)对Error类或其子类的对象,程序中不必进行处理;
(2)对RuntimeException类或其子类,程序中可以不必进行处理;
除此之外的异常,程序员都应该在程序中进行处理。要么用try-catch-finally进行捕获处理,要么明确表示不处理从而声明抛出异常(throws),要么先捕获处理然后再次抛出。
(3)Java的异常处理机制(try-catch-finally语句、throws 子句、throw 语句)带来Java程序代码结构上的改变。
(4)不能滥用异常机制。简单的出错判断建议用if语句。
(5)不要过分细分异常。