一.基本异常
1. 抛出异常的原理
1) 像产生一个Java对象那样在heap上以new产生一个异常对象。
2) 停止目前的执行路线,将上述那个异常对象的reference自目前的context丢出。
3) 异常处理机制接手工作,寻找得以继续执行的适当地点。
2. 产生一个异常对象
异常类有两个构造函数:一个default构造函数;一个带String型参数的构造函数,参数的信息可以通过异常类中的各种方法取出。
3. 异常类的结构
1) Error是一些编译期错误或系统错误,一般无需在程序中捕捉到Error异常。
2) Exception是我们能捕捉到的异常,其中Exception异常又分为RuntimeException和non-RuntimeException两大类异常。
二.异常的捕捉和处理
1. 异常的捕捉
1.1 通过try…catch就可捕捉异常
import java.lang.RuntimeException;
import java.lang.NullPointerException;
import java.sql.SQLException;
import java.io.IOException;
class TestException{
public void testSQLException() throws SQLException {
throw new SQLException();
}
public void testIOException() throws IOException {}
}
public class Test{
public static void main(String[] args){
TestException te = new TestException();
try{
te.testSQLException();
te.testIOException();
}
catch(SQLException ex){
System.out.println("catch SQLException in main");
}
catch(IOException ex){
System.out.println("catch IOException in main");
}
catch(Exception ex){ //(1)
System.out.println("catch Exception in main");
}
}
}
运行结果为:catch SQLException in main
只有参数类型与异常类型相同或相近的catch会被执行。
1.2 异常处理的讨论
1.2.1 当try中的语句产生异常时,在异常处理函数捕捉了该异常而又没有重新抛出异常时,则在执行完处理函数后,将跳出发生异常的try块,接着执行下面的语句:
import java.sql.SQLException;
class TestException{
public static void tSql() throws SQLException {
System.out.println("Originating the exception in tSql()");
throw new SQLException("throw in tSql");
}
public void f() throws SQLException{
try{
tSql();
}
catch(SQLException ex){
System.out.println("catch SQLException in f()");
//throw ex;(1)
}
System.out.println("after exception handle in f()");//(2)
}
}
public class Test{
public static void main(String[] args){
TestException te = new TestException();
try{
te.f();
}
catch(SQLException ex){
System.out.println("catch te.f() SQLException in main");
}
catch(Exception ex){
System.out.println("catch te.f() Exception in main");
}
}
}
运行结果为:
Originating the exception in tSql()
catch SQLException in f()
after exception handle in f()
在f()函数中执行完异常处理函数后,将继续执行发生异常的try….catch外的代码(2)。
1.2.2 当try中的语句产生异常时,在异常处理函数捕捉了该异常而又重新抛出异常时,则将把异常抛出到上一层context中,发生异常的语句之后的代码将不执行。
如果去年上面代码中(1)处的注释,那么运行结果变为:
Originating the exception in tSql()
catch SQLException in f()
catch te.f() SQLException in main
由于在(1)处重新抛出了异常,所以(2)处代码没有被执行。
1.2.3 如果没处理相应异常的处理函数,将把异常抛出到上一层context中,发生异常的语句之后的代码将不执行。
import java.sql.SQLException;
class TestException{
public static void tSql() throws SQLException {
System.out.println("Originating the exception in tSql()");
throw new SQLException("throw in tSql");
}
public void f() throws SQLException{
int x = 0;
System.out.println("10/" + x + " = " + 10/x);//(1)
System.out.println("after exception handle in f()");
}
}
public class Test{
public static void main(String[] args){
TestException te = new TestException();
try{
te.f();
}
catch(SQLException ex){
System.out.println("catch te.f() SQLException in main");
}
catch(Exception ex){
System.out.println("catch te.f() Exception in main");
}
}
}
运行结果为:
catch te.f() Exception in main
在代码(1)处发生了异常,但在f()函数中没有对它进行处理,所以它会被抛出到上一层context中并跳出f()函数。
1.3 捕捉所有异常
如果想捕捉所有异常,只要捕捉Exception异常就行,如上面代码的(1)处