java异常处理 try catch finally

来源:互联网 发布:python标准输入输出 编辑:程序博客网 时间:2024/05/16 09:55

Java中的异常分为两大类:

  1.Checked Exception(非Runtime Exception)

  2.Unchecked Exception(Runtime Exception)

运行时异常:RuntimeException类是Exception类的子类,它叫做运行时异常,Java中的所有运行时异常都会直接或者间接地继承自RuntimeException类,运行时异常,是在编译的时候检测不到,只有在运行时候才会出现,这些异常是可以通过程序员的谨慎避免的,比如说空指针异常,数组下标越界等。

非运行时异常:Java中凡是继承自Exception,而不继承自RuntimeException类的异常都是非运行时异常。这是我们编程人员无法避免和控制的异常,比如说创建读取文件的流,会出现文件不存在异常。

 

异常处理的一般结构

  1.   try {  
  2.     // 可能会发生异常的程序代码  
  3. catch (Type1 id1) {  
  4.     // 捕获并处理try抛出的异常类型Type1  
  5. catch (Type2 id2) {  
  6.     // 捕获并处理try抛出的异常类型Type2  
  7. finally {  
  8.     // 无论是否发生异常,都将执行的语句块  




finally 块:无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。在以下4种特殊情况下,finally块不会被执行:
1)在finally语句块中发生了异常。
2)在前面的代码中用了System.exit()退出程序。
3)程序所在的线程死亡。
4)关闭CPU。

总结:

1)try 块:用于捕获异常。其后可接零个或多个catch块,零个或者一个finally块。如果没有catch块,则必须跟一个finally块;

2)当try语句块里的某条语句出现异常时,而没有处理此异常的catch语句块或者根本没有catch块的时候(没有catch块,必须有一个finally块。如果函数声明时,注明throws 异常,这个异常将由调用者处理,否则,此异常将会抛给JVM处理。无论如何,finally语句块里的语句还是会被执行,但finally语句块后的任何语句不会被执行,也就是finally语句块后的代码都是不可达的;

3)在try语句块中是按照顺序来执行的,当执行到某一条语句出现异常时,出现异常之后的语句也不会被执行。程序将跳到catch语句块,并按照顺序查询catch块的Exception类型,找到后进入catch执行语句,其他的catch语句块将不会被执行,catch语句块执行完后,执行finally语句块里的语句,最后执行finally语句块后的语句;

4)使用throws关键字将异常抛给调用者后,如果调用者不想处理该异常,可以继续向上抛出,但最终要有能够处理该异常的调用者

5)在 try-catch-finally 结构中,可重新抛出异常。

 

重申:

1)由于运行异常是我们在编写代码的时候无法预料的,所以一般不会有异常处理try catch块,这中情况下,出现异常,整个程序就死掉了,死在出现异常的语句,之后的程序都不会运行。

2)当一个块中(try块,catch块,finally块),执行某个语句出现异常,则,这个块中,异常语句下的语句都不会执行。

3)try中的异常,由catch块接受和处理。catch 和finally 块中出现的异常,可以接着嵌套try,catch,也可以在函数声明时候throws 向上抛出异常,由调用者处理。如果这些都没有,此异常将会抛给JVM处理。



这有个看起来好长好长的代码,其实一点也不多,做做看,对了,就说明异常玩的溜啦~

  1. public class TestException {  
  2.     public TestException() {  
  3.     }  
  4.   
  5.     boolean testEx() throws Exception {  
  6.         boolean ret = true;  
  7.         try {  
  8.             ret = testEx1();  
  9.         } catch (Exception e) {  
  10.             System.out.println("testEx, catch exception");  
  11.             ret = false;  
  12.             throw e;  
  13.         } finally {  
  14.             System.out.println("testEx, finally; return value=" + ret);  
  15.             return ret;  
  16.         }  
  17.     }  
  18.   
  19.     boolean testEx1() throws Exception {  
  20.         boolean ret = true;  
  21.         try {  
  22.             ret = testEx2();  
  23.             if (!ret) {  
  24.                 return false;  
  25.             }  
  26.             System.out.println("testEx1, at the end of try");  
  27.             return ret;  
  28.         } catch (Exception e) {  
  29.             System.out.println("testEx1, catch exception");  
  30.             ret = false;  
  31.             throw e;  
  32.         } finally {  
  33.             System.out.println("testEx1, finally; return value=" + ret);  
  34.             return ret;  
  35.         }  
  36.     }  
  37.   
  38.     boolean testEx2() throws Exception {  
  39.         boolean ret = true;  
  40.         try {  
  41.             int b = 12;  
  42.             int c;  
  43.             for (int i = 2; i >= -2; i--) {  
  44.                 c = b / i;  
  45.                 System.out.println("i=" + i);  
  46.             }  
  47.             return true;  
  48.         } catch (Exception e) {  
  49.             System.out.println("testEx2, catch exception");  
  50.             ret = false;  
  51.             throw e;  
  52.         } finally {  
  53.             System.out.println("testEx2, finally; return value=" + ret);  
  54.             return ret;  
  55.         }  
  56.     }  
  57.   
  58.     public static void main(String[] args) {  
  59.         TestException testException1 = new TestException();  
  60.         try {  
  61.             testException1.testEx();  
  62.         } catch (Exception e) {  
  63.             e.printStackTrace();  
  64.         }  
  65.     }  

答案:

i=2
i=1
testEx2, catch exception
testEx2, finally; return value=false
testEx1, finally; return value=false
testEx, finally; return value=false


这道题,折腾我好久,终于懂得,为什么2在catch中throw e ,然而 1 却没有进行catch啦,而是正常的运行try块,引用我群里头的一位哥哥的回答,大家一看就懂啦!


调用方法的时候,会有一个方法栈帧, 先执行testEx2 的 catch里面的throw e, 相当于把e压入到这个栈中,但是方法并没有退出,接着执行finally,finally是一定会执行的你肯定知道吧,finally里面return ret,相当于把ret又压到栈顶。这时候方法结束,弹出栈顶元素return false 作为结果。所以你throw出来的e相当于被覆盖了。 之前有个很经典的问题就是 return  和 finally 哪个先执行,其实是  return 后面的表达式会先被执行,把结果压入栈中,然后执行finally中的表达式,最后方法结束,弹出栈顶元素。

ok 异常搞明白了!!


自定义java异常

public Myexception extends Exception{

 public  Myexception (String errorMessage ){

   super (errorMessage);

     }

}

方法被覆盖时,必须抛出相同的异常,或者是异常的子类

如果父类抛出多个异常,则覆盖方法必须抛出异常的子集,不能抛出新异常.

1 0
原创粉丝点击