您的位置:首页 > 编程语言 > Java开发

java异常处理

2015-09-01 13:35 357 查看
try...catch...finally我们经常在代码中用到了,一直觉得这个东西没有太大的用处。因为在开发中,我们总是很坚信我们的代码是不会出错的。这样说来,问题就来了,一旦我们的系统出了错,没有它们,系统就会崩溃,反映给用户,用户就不会再用这个系统。

一、Java异常

异常指不期而至的各种状况,如:文件找不到、网络连接失败、空指针、类找不到、非法参数等等。异常是一个事件,它发生在异常运行期间,干扰了正常的指令流程。Java通过API中的Throwable类的众多子类描述各种不同的异常。因此,Java异常也是异常,是Throwbale子类的实例。

Java异常类层次结构图



从图中我们可以看到,Throwable作为一个类,有两个重要的子类:

Error(错误):程序是无法处理的,一旦遇到,系统崩溃,无法继续运行,表示运行应用程序中较严重的问题。

Exception(异常):程序本身可以进行处理的异常。一般可以分为两类:Io流出和运行异常。

二、处理异常机制

在Java应用程序中,异常处理机制:抛出异常,捕捉异常。

抛出异常:当一个方法出现错误引发宜昌市,方法创建异常对象并交付运行时系统,异常对象中包含了异常类型和异常出现时的程序状态等异常信息。通常我们用throw将异常抛给调用它的方法。

捕捉异常:在方法抛出一场之后,运行时系统将转为寻找合适的异常处理器。在方法抛出异常之后,运行时系统将转为寻找合适的异常处理器(exception handler)。潜在的异常处理器是异常发生时依次存留在调用栈中的方法的集合。当异常处理器所能处理的异常类型与方法抛出的异常类型相符时,即为合适 的异常处理器。运行时系统从发生异常的方法开始,依次回查调用栈中的方法,直至找到含有合适异常处理器的方法并执行。当运行时系统遍历调用栈而未找到合适
的异常处理器,则运行时系统终止。同时,意味着Java程序的终止。

对于运行时异常、错误或可查异常,Java技术所要求的异常处理方式有所不同。

由于运行时异常的不可查性,为了更合理、更容易地实现应用程序,Java规定,运行时异常将由Java运行时系统自动抛出,允许应用程序忽略运行时异常。

对于方法运行中可能出现的Error,当运行方法不欲捕捉时,Java允许该方法不做任何抛出声明。因为,大多数Error异常属于永远不能被允许发生的状况,也属于合理的应用程序不该捕捉的异常。

对于所有的可查异常,Java规定:一个方法必须捕捉,或者声明抛出方法之外。也就是说,当一个方法选择不捕捉可查异常时,它必须声明将抛出异常。

一个方法所能捕捉的异常,一定是java代码在某处抛出的异常。简单地说,异常总是先被抛出,后被捕捉的。

一个方法中抛出的任何异常都必须使用throws字句。

1、捕捉异常

通常使用try-catch或者try-catch-finally语句实现。

(1)、try-catch

实例:

[java] view
plaincopyprint?

public class TestException {

public static void main(String[] args) {

int[] intArray = new int[3];

try {

for (int i = 0; i <= intArray.length; i++) {

intArray[i] = i;

System.out.println("intArray[" + i + "] = " + intArray[i]);

System.out.println("intArray[" + i + "]模 " + (i - 2) + "的值: "

+ intArray[i] % (i - 2));

}

} catch (ArrayIndexOutOfBoundsException e) {

System.out.println("intArray数组下标越界异常。");

} catch (ArithmeticException e) {

System.out.println("除数为0异常。");

}

System.out.println("程序正常结束。");

}

}

上面的代码中捕获两个错误:除数为0和数组下标越界异常。运行结果:

intArray[0] = 0

intArray[0]模 -2的值: 0

intArray[1] = 1

intArray[1]模 -1的值: 0

intArray[2] = 2

除数为0异常。

程序正常结束。

我们运行就会发现当捕捉到第一个错误的时候,系统将不再执行try之后的代码,运行先捕捉到除数为0的错误,因此,而后的处理结束,就以为这整个try-catch语句结束。

Java通过异常类描述异常类型,异常类的层次结构如图1所示。对于有多个catch子句的异常程序而言,应该尽量将捕获底层异常类的catch子 句放在前面,同时尽量将捕获相对高层的异常类的catch子句放在后面。否则,捕获底层异常类的catch子句将可能会被屏蔽。

(2)、try-catch-finally

不管catch有没有异常捕获,finally都是会运行的。

图示try-catch-finally语句的执行:



2、抛出异常

(1)、throws抛出异常

如果一个方法可能会出现异常,但没有能力处理这种异常,可以在方法声明处用throws子句来声明抛出异常。例如汽车在运行时可能会出现故障,汽车本身没办法处理这个故障,那就让开车的人来处理。

throws语句用在方法定义时声明该方法要抛出的异常类型,如果抛出的是Exception异常类型,则该方法被声明为抛出所有的异常。多个异常可使用逗号分割。throws语句的语法格式为:

[java] view
plaincopyprint?

methodname throws Exception1,Exception2,..,ExceptionN

{

}

使用throws关键字将异常抛给调用者后,如果调用者不想处理该异常,可以继续向上抛出,但最终要有能够处理该异常的调用者。

一般,我们使用异常,将异常抛给UI,通过Error页面,进行处理,这样给用户体验会好一些。

(2)、throw抛出异常

throw通常出现在函数体中,用来抛出一个Throwable类型的异常。程序会在throw语句会立即终止,它之后的代码是不会执行的。

[java] view
plaincopyprint?

<span style="font-family:KaiTi_GB2312;font-size:18px;">package Test;

import java.lang.Exception;

public class TestException {

static int quotient(int x, int y) throws MyException { // 定义方法抛出异常

if (y < 0) { // 判断参数是否小于0

throw new MyException("除数不能是负数"); // 异常信息

}

return x/y; // 返回值

}

public static void main(String args[]) { // 主方法

int a =3;

int b =0;

try { // try语句包含可能发生异常的语句

int result = quotient(a, b); // 调用方法quotient()

} catch (MyException e) { // 处理自定义异常

System.out.println(e.getMessage()); // 输出异常信息

} catch (ArithmeticException e) { // 处理ArithmeticException异常

System.out.println("除数不能为0"); // 输出提示信息

} catch (Exception e) { // 处理其他异常

System.out.println("程序发生了其他的异常"); // 输出提示信息

}

}



}

class MyException extends Exception { // 创建自定义异常类

String message; // 定义String类型变量

public MyException(String ErrorMessagr) { // 父类方法

message = ErrorMessagr;

}



public String getMessage() { // 覆盖getMessage()方法

return message;

}

} </span>

要注意的是,throw 抛出的只能够是可抛出类Throwable 或者其子类的实例对象。

如果抛出了检查异常,则还应该在方法头部声明方法可能抛出的异常类型。该方法的调用者也必须检查处理抛出的异常。

总结:

异常在程序中是不可以被取代的,更不能不写,这是很危险的一件事情,异常体现了一个程序员的专业性,更能体现一个程序员的全局观。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: