Java异常
1. 异常的含义
异常是正常情况以外的事件,具有不确定性。例如:用户输入错误、除数为0、需要的文件不存在或者打不开、数组下标越界、传入参数为空或不符合指定范围等。
下边的例子将产生一个除0的异常。程序在执行到c=a/b时,由于b=0而造成除数为0,系统自动产生一个异常对象,此时程序将不执行异常点以后的程序,而直接交给系统(java虚拟机)处理,给出程序异常后退出程序:
【例1】
public class ExampleException {
public static void main(String args[]){
int a,b,c;
a=67;b=0;
c=a/b;
System.out.println(a+"/"+b+"="+c);
}
}
运行结果:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at test.ExampleException.main(ExampleException.java:7)
2. 异常的分类
java采用面向对象的方式进行异常处理,所有异常的对象祖先类都是Exception类,其继承关系如下图:
Throwable: 有两个重要的子类:Exception(异常)和 Error(错误),二者都是 Java 异常处理的重要子类,各自都包含大量子类。
Error(错误):是程序无法处理的错误,表示运行应用程序中较严重问题。
大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题。例如,Java虚拟机运行错误(Virtual MachineError),当 JVM 不再有继续执行操作所需的内存资源时,将出现 OutOfMemoryError。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。
Exception(异常):是程序本身可以处理的异常 注意:异常和错误的区别:异常能被程序本身可以处理,错误是无法处理 通常,Java的异常(包括Exception和Error)分为可查的异常(checked exceptions)和不可查的异常(unchecked exceptions)。
3. 异常的处理
1.隐式声明抛出
这类异常的特点是:异常类型是RuntimeException或者其子类,程序方法可以对异常不做任何声明抛出或处理,直接交给调用该方法的地方处理,程序能编译通过,不会对可能产生异常的代码行给出提示。
【例2】
public class TestArray {
private static int[] x;
public static void main(String args[]){
System.out.println(x[0]);
}
}
运行结果:Exception in thread "main" java.lang.ArithmeticException: / by zero
上述程序会发生数组越界异常,类似的还有pop时的空栈异常、数组空指针异常等,这些都是RuntimeException异常。
【例3】import java.io.*;
public class Test {
public static void main(String args[]){
BufferedReader keyin = new BufferedReader(new InputStreamReader(System.in));
String c1;
int i=0;
String[] e=new String[10];
while(i<10){
c1=keyin.readLine(); //系统提示错误!
e[i]=c1;
i++;
}
}
}
系统提示:Unhandled exception type IOException
原因是readLine()方法啊有可能发生IOException异常,它和RuntimeException是平行类,所以不能隐式抛出。
2.显示声明抛出
只需将public static void main(String args[]) 修改为
public static void main(String args[]) throws IOException
其含义是:如果main中readLine()方法处发生异常,main不负责异常处理,由调用main方法的地方去处理异常,而调用main方法的java虚拟机,因此由java虚拟机进行默认处理。
注意:当子类覆盖父类的方法时,子类抛出的异常类应和父类抛出的异常相同或者为其子类,不能为其父类。
3.捕获处理
捕获处理是由try-catch-finally组成的一个异常处理块构成,其格式如下:
try {
// 可能会发生异常的程序代码 }
catch (Type1 id1){
// 捕获并处置try抛出的异常类型Type1 }
catch (Type2 id2){
//捕获并处置try抛出的异常类型Type2 }
...
Finally { //收尾工作
Finally Handling }
Try语句块含有可能发生异常的程序代码,可能抛出一个或多个异常,因此,try后面可有一个或多个catch,需要说明的是,当try语句块没有异常发生时,紧跟其后的catch代码块并不执行。
4.异常的嵌套处理
异常的嵌套处理程序中,最内层的try产生的异常,如果不能被对应的catch异常类声明引用,则转交给外层的catch去处理。