Java异常处理体系

       Java把所有非正常情况分为两种:异常(Exception)和错误(Error),它们都继承Throwable父类。

Error错误,一般是指与虚拟机相关的问题,如系统崩溃、虚拟机错误,动态链接失败等,这种错误无法恢复,不可捕捉,将导致应用程序中断。

       异常捕获时,先捕获小异常,再捕获大异常。即所有父类异常的catch块都应该排在子类异常catch块的后面,否则编译出错。

Java7以前,每个catch块只能捕获一种类型的异常;从Java7开始,可以捕获多中类型的异常。

(1)捕获多种类型的异常时,多种异常类型之间用竖线( | )隔开;

(2)捕获多种类型的异常时,异常变量有隐式的final修饰,因此不能对异常变量重新赋值。

捕获一种异常时,异常变量没有final修饰。

finally回收资源

不管try块中的代码是否出现异常,也不管那个catch块被执行,甚至在try和catch块中都使用了return语句,finally块总会被执行,除非在try块执行之前,被return或者在finally块之前调用了System.exit(1)语句退出虚拟机。

Demo1:

  private static int test1() {
         int i = 1;
         try {
	            System.out.println("test1===========try...");
	            i = i+1;
	            return i;
	        } catch (Exception e) {
	            System.out.println("test1===========catch...");
	        } finally {
	            i++;
	            System.out.println("test1===========finally...");
	            System.out.println("test1===========i=" + i);
	        }
	   return i;
  }


结论:finally代码块是在try代码块中的return语句执行之后,返回之前执行的。

Demo2:

@SuppressWarnings("finally")
private static int test2() {
        int i = 1;
        try {
            System.out.println("test2===========try...");
            return i += 1;
        } catch (Exception e) {
            System.out.println("test2===========catch...");
        } finally {
            i++;
            System.out.println("test2===========finally...");
            System.out.println("test2===========i=" + i);
            return i;
        }
}

结论:finally代码块中的return语句会覆盖try代码块中的return语句。

Demo3:

private static HashMap<String, String> test3() {
	HashMap<String, String> map = new HashMap<String, String>();
        map.put("key", "init");
        try {
            System.out.println("test3===========try...");
            map.put("key", "try");
            return map;
        } catch (Exception e) {
            System.out.println("test3===========catch...");
            map.put("key", "catch");
        } finally {
            System.out.println("test3===========finally...");
            map.put("key", "finally");
            map=null;
        }
	return map;
}

对比Demo1和Demo3发现

如果finally语句中没有用return语句覆盖返回值,那么原来的返回值可能因为finally块里的修改而改变也可能不变。传值类型的返回值:不变;传址类型的返回值:会变。传值:8种基本数据类型及其包装类,字符常量。传址:数组和对象。

在Demo3中的finally块中我把map设置为null,为什么返回的值还是“test3={key=finally}”?

        程序在执行到try{}语句中的return方法后,就会先返回相应的值,并把相应的值(map的引用地址值)存储在一个临时栈中去保存这个结果。在finally执行完后,方法全部执行完,这时会再次调用return方法,这时不在是返回值,而是告诉主调程序,被调程序已经执行完了,可以接着去执行主程序中的其它方法了。此时返回的值还是原来保存在临时栈中的值,所以map的不是null。

Demo4:

try块,finally块没有返回值的时候,代码顺序执行





猜你喜欢

转载自blog.csdn.net/jingshenbusi/article/details/78822391