java异常处理
#异常的分类
首先,复习前面方法声明的5要素:
访问修饰符 返回值类型 方法名 参数表 抛出异常
例子:
static void mc(int a) throws FileNotFoundException, EOFException, SQLException{
//函数体
System.out.println("mc 1");
if (i==0) throw new NullPointerException();
if (i==1) throw new FileNotFoundException();
if (i==2) throw new EOFException();
if (i==3) throw new SQLException();
System.out.println("mc 2");
}
throws关键字是异常超出的声明,要和throw关键字区别开,throw抛出是一个动作。
前面的四个已经都学过,现在来学习异常。当发生异常时要告诉程序应该怎么做,如银行取款机出现故障时,网络连接不上时应该怎么做?
#所有错误的父类:Throwable
如上的API,其有两个直接的子类:Error和Exception,Error是一种错误,无法避免的也是无法挽回的,所以不在我们的处理范围。我们要处理的是Exception,(如下图)而Exception又有一个子类叫:RuntimeException是一个未检查异常,未检查就是说程序员没有好好检查程序引起的异常,如果好好检查是可以避免的,所以这种异常可以处理也可以不处理。除了RuntimeException之外的都是已检查异常,是无法避免的,如地震,我们一定要有对策。
#异常的抛出
用throw抛出异常,异常会沿着方法调用链反向传递。
#异常对象的处理
##一直向上抛出,本方法不处理
import java.util.*;
import java.io.*;
import java.sql.*;
public class TestException{
public static void main(String[] args) throws Exception{//最后主函数抛给JVM,JVM就会停止程序的运行
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
System.out.println("main 1");
ma(i);
System.out.println("main 2");
}
static void ma(int i) throws Exception{//一直向上抛出
System.out.println("ma 1");
mb(i);
System.out.println("ma 2");
}
static void mb(int i) throws IOException, SQLException{//把多态用在异常的抛出上,父类包含了子类
System.out.println("mb 1");
mc(i);
System.out.println("mb 2");
}
static void mc(int i) throws FileNotFoundException,EOFException, SQLException{
System.out.println("mc 1");
if (i==0) throw new NullPointerException();//这是一个未检查异常,所有的方法都会默认抛出未检查异常,所以我们不用声明去抛出未检查异常
if (i==1) throw new java.io.FileNotFoundException();
if (i==2) throw new java.io.EOFException();
if (i==3) throw new java.sql.SQLException();
System.out.println("mc 2");
}
}
输入1时,结果如下:
1
Exception in thread "main" main 1
ma 1
mb 1
mc 1
java.io.FileNotFoundException
at chp8_final.TestException.mc(TestException.java:26)
at chp8_final.TestException.mb(TestException.java:20)
at chp8_final.TestException.ma(TestException.java:15)
at chp8_final.TestException.main(TestException.java:10)
输入0时:
0
main 1
ma 1
Exception in thread "main" mb 1
mc 1
java.lang.NullPointerException
at chp8_final.TestException.mc(TestException.java:25)
at chp8_final.TestException.mb(TestException.java:20)
at chp8_final.TestException.ma(TestException.java:15)
at chp8_final.TestException.main(TestException.java:10)
上面这种一直向上抛出的处理方式很消极。
##捕获异常
除了通过 throws 进行消极处理之外,我们同样可以进行一些积极处理。 我们可以采用
try-catch 的语法来捕获可能抛出的异常。
try-catch 的语法结构如下:
try{
可能发生异常的代码;
}catch(捕获的异常类型 1 e){
异常处理 1…
}catch(捕获的异常类型 2 e){
异常处理 2…
} catch(捕获的异常类型 n e){
异常处理 n…
}
如果在 try 语句块中没有出现异常,那么任何一个 catch 语句块都不会得到执行。但一
旦 try 块中出现了异常,程序的流程会马上跳出 try 块,根据异常类型的不同,进入某一个
catch 语句块。随后,这个异常被宣告处理完毕,程序将继续向下正常运行。
###修改之后的程序
package chp8_final;
import java.util.*;
import java.io.*;
import java.sql.*;
public class TestException{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
System.out.println("main 1");
ma(i);
System.out.println("main 2");
}
static void ma(int i) {
try{
System.out.println("ma 1");
mb(i);
System.out.println("ma 2");
}catch(IOException ioe){
System.out.println("IOException");
}catch(SQLException sqle){
System.out.println("SQLException");
}catch(Exception e){
System.out.println("Exception");
}
}
static void mb(int i) throws IOException, SQLException{
System.out.println("mb 1");
mc(i);
System.out.println("mb 2");
}
static void mc(int i) throws FileNotFoundException,
EOFException, SQLException{
System.out.println("mc 1");
if (i==0) throw new NullPointerException();
if (i==1) throw new java.io.FileNotFoundException();
if (i==2) throw new java.io.EOFException();
if (i==3) throw new java.sql.SQLException();
System.out.println("mc 2");
}
}
输入0时的结果为:
main 1
ma 1
mb 1
mc 1
Exception
main 2
catch语句块里面就是对异常的处理,处理完异常之后,程序继续往下走打印mian 2。
由于 Exception 是所有异常类的父类,根据多态,捕获 Exception 类也就
是捕获其任何一种子类异常。所以在捕获是的代码中不能把Exception放在前面。
应该放在最后的部分:
static void ma(int i) {
try{
System.out.println("ma 1");
mb(i);
System.out.println("ma 2");
}
//!下面的代码编译出错!
catch(Exception e){
System.out.println(“Exception”);
}catch(IOException ioe){
System.out.println(“IOException”);
}catch(SQLException sqle){
System.out.println(“SQLException”);
}
}
注意,捕获子类异常的 catch 语句写在前面,捕获父类异常的 catch 语句写在后面。