Java通过面向对象的方法进行异常处理,对各种不同的异常进行分类,并提供良好的接口。在Java 中,每个异常都是一个对象,它是 Throwable 类或其他子类的实例。当一个方法出现异常后便抛出一个异常对象,该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并进行处理。(异常处理的任务是将程序从错误的状态中恢复,继续运行)Java的异常处理是通过try、catch、throw、throws和finally来实现。
try指定预防所有“异常”的程序;
catch来指定要捕捉的“异常”类型;
throw 用来明确地抛出一个“异常”;
throws用来声明可能抛出的异常;
finally为确保一段代码不管发生什么“异常”都被执行。
try
try{
code // 可能产生异常的代码
}
try块不单独使用,要处理发生的异常需要配合catch和finally(至少一个catch或一个finally)
catch
try{
code 1
code 2 // 注意:若code 1 产生异常,接下来会去匹配catch语句,执行catch,不会再执行code 2了
}
catch(ExpectionType e1){
code // 异常处理代码
}
catch(ExpectionType e2){
code // 异常处理代码
}
catch(ExceptionType1 | ExpectionType2 e3){ // 多重异常捕获 java7以后支持 可以用来对不同的异常进行相同的处理
code // 异常处理代码
}
-
一个try块可能会引起多种异常,catch块可以有多个
-
异常类型检查顺序是自上而下,若与第一个catch匹配则第一个catch块被执行,不再执行下面的;如果与第一个不匹配,则继续向下匹配
-
多重异常捕获,异常类型之间用管道符 | 分开
注意:子异常类的catch必须在前,父异常类的catch在后,否则永远不会执行子类的catch块,而且编译器也会报错 。即e1不能是e2的父类
注意:若code 1 产生异常,接下来会去匹配catch语句,执行catch,不会再执行code 2了
finally
try{
code
return ;
}
catch(Exception e){
code
return ;
}
finally{
code // 处理异常、回收资源
}
存在try块时总会执行finally块,无论catch块执行不执行(有没有异常),finally都会执行。
finally会在执行try程序段后的程序段前执行。
throw
格式:
throw 异常对象;
throw new 异常类名();
public class demo1 {
static void test1(){
try{
throw new ExceptionType(); // throw抛出一个异常e
}
catch (ExceptionType e){ // 抛出的异常e可以在这处理,如果在这处理了,就不会到上一级处理了
System.out.println("test1_e");
}
}
public static void main(String[] args) {
try{
test1(); // 调用
}
catch(ExceptionType e) {
System.out.println("main_e"); // 异常e也可以在这处理,前提是还能到这
}
}
}
看一个我们平时可能会碰到的抛出异常的结果:
3 public class demo2 {
4 static void test2(){
5 throw new NullPointerException("null"); //抛出一个空指针异常
6 }
7
8 public static void main(String[] args) {
9 test2();
10 }
11 }
结果: Exception in thread "main" java.lang.NullPointerException: null at pc.demo2.test2(demo2.java:5) at pc.demo2.main(demo2.java:9) Process finished with exit code 1
throws
throws只能声明异常,声明异常是指一个方法不处理它产生的异常,而是向上传递,谁调用这个方法就由谁处理。
public class demo2{
static void test2() throws NullPointerException{
throw new NullPointerException("null");
}
public static void main(String[] args) {
try{
test2();
}
catch(Exception e){
System.out.println(e);
}
}
}
同时声明多种异常:throws ExceptionType1, ExceptionType2, ......
注意:如果只声明了异常而没有捕捉,会报错
try语句嵌套
可以在一个成员方法调用的外面写一个try语句,在这个成员方法内部,写另一个try语句保护其他代码。每当遇到一个try语句,异常的框架就放到堆栈上面,直到所有的try语句都完成。如果下一级的try语句没有对某种异常进行处理,堆栈就会展开,直到遇到有处理这种异常的try语句。
// 上面这段话是我抄书上的,下面是我理解这句话后写的,我理解的应该没错吧
public class demo1 {
static void test1(){
try{
new FileOutputStream("a.txt"); //不看
throw new NullPointerException("null"); // 抛出一个空指针异常
}
catch (FileNotFoundException e){ // 不匹配处理不了
System.out.println("test1_notFind");
}
}
public static void main(String[] args) {
try{
test1(); // 调用
}
catch(NullPointerException e) { // 在这处理
System.out.println("main_NULL");
}
}
}
异常类浅析: