Day27---学习Java第二弹

2021-08-06

Java异常方法

2. try-catch-finally语句

      try-catch语句还可以包括第三部分,就是finally子句。它表示无论是否出现异常,都应当执行的内容。try-catch-finally语句的一般语法形式为:

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

例5  带finally子句的异常处理程序。

public class TestException {
    public static void main(String args[]) {
        int i = 0;
        String greetings[] = { " Hello world !", " Hello World !! ",
                " HELLO WORLD !!!" };
        while (i < 4) {
            try {
                // 特别注意循环控制变量i的设计,避免造成无限循环
                System.out.println(greetings[i++]);
            } catch (ArrayIndexOutOfBoundsException e) {
                System.out.println("数组下标越界异常");
            } finally {
                System.out.println("--------------------------");
            }
        }
    }
}

运行结果:

Hello world !

--------------------------

Hello World !!

--------------------------

HELLO WORLD !!!

--------------------------

数组下标越界异常

--------------------------

在例5中,请特别注意try子句中语句块的设计,如果设计为如下,将会出现死循环。如果设计为:

try {
      System.out.println (greetings[i]); i++;
}

小结:

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

catch 块:用于处理try捕获到的异常。

finally 块:无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return语句时,

finally语句块将在方法返回之前被执行。在以下4种特殊情况下,finally块不会被执行:

1)在finally语句块中发生了异常

2)在前面的代码中用了System.exit()退出程序。

3)程序所在的线程死亡。

4)关闭CPU。

 

 

3. try-catch-finally 规则(异常处理语句的语法规则):

1) 必须在 try 之后添加 catch 或 finally 块。try 块后可同时接 catch 和 finally 块,但至少有一个块。

2) 必须遵循块顺序:若代码同时使用 catch 和 finally 块,则必须将 catch 块放在 try 块之后。

3) catch 块与相应的异常类的类型相关。

4) 一个 try 块可能有多个 catch 块。若如此,则执行第一个匹配块。即Java虚拟机会把实际抛出的异常对象依次和各个

catch代码块声明的异常类型匹配,如果异常对象为某个异常类型或其子类的实例,就执行这个catch代码块,不会再执行其他的 catch代码块

5) 可嵌套 try-catch-finally 结构。

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

7) 除了下列情况,总将执行 finally 做为结束:JVM 过早终止(调用 System.exit(int));

在 finally 块中抛出一个未处理的异常;计算机断电、失火、或遭遇病毒攻击。

4. try、catch、finally语句块的执行顺序:

 

1)当try没有捕获到异常时:try语句块中的语句逐一被执行,程序将跳过catch语句块,执行finally语句块和其后的语句;

2)当try捕获到异常,catch语句块里没有处理此异常的情况:当try语句块里的某条语句出现异常时,

而没有处理此异常的catch语句块时,此异常将会抛给JVM处理,finally语句块里的语句还是会被执行,但finally语句块后的语句不会被执行;

3)当try捕获到异常,catch语句块里有处理此异常的情况:在try语句块中是按照顺序来执行的,

当执行到某一条语句出现异常时,程序将跳到catch语句块,并与catch语句块逐一匹配,找到与之对应的处理程序,

其他的catch语句块将不会被执行,而try语句块中,出现异常之后的语句也不会被执行,catch语句块执行完后,

执行finally语句块里的语句,最后执行finally语句块后的语句;

 

Throws抛出异常的规则:

1) 如果是不可查异常(unchecked exception),即Error、RuntimeException或它们的子类,

那么可以不使用throws关键字来声明要抛出的异常,编译仍能顺利通过,但在运行时会被系统抛出。

2)必须声明方法可抛出的任何可查异常(checked exception)。即如果一个方法可能出现受可查异常,

要么用try-catch语句捕获,要么用throws子句声明将它抛出,否则会导致编译错误

3)仅当抛出了异常,该方法的调用者才必须处理或者重新抛出该异常。当方法的调用者无力处理该异常的时候,应该继续抛出,而不是囫囵吞枣。

4)调用方法必须遵循任何可查异常的处理和声明规则。若覆盖一个方法,则不能声明与覆盖方法不同的异常。

声明的任何异常必须是被覆盖方法所声明异常的同类或子类。

void method1() throws IOException{}  //合法  
 
//编译错误,必须捕获或声明抛出IOException  
void method2(){  
  method1();  
}  
 
//合法,声明抛出IOException  
void method3()throws IOException {  
  method1();  
}  
 
//合法,声明抛出Exception,IOException是Exception的子类  
void method4()throws Exception {  
  method1();  
}  
 
//合法,捕获IOException  
void method5(){  
 try{  
    method1();  
 }catch(IOException e){…}  
}  
 
//编译错误,必须捕获或声明抛出Exception  
void method6(){  
  try{  
    method1();  
  }catch(IOException e){throw new Exception();}  
}  
 
//合法,声明抛出Exception  
void method7()throws Exception{  
 try{  
  method1();  
 }catch(IOException e){throw new Exception();}  
} 

判断一个方法可能会出现异常的依据如下:

1)方法中有throw语句。例如,以上method7()方法的catch代码块有throw语句。

2)调用了其他方法,其他方法用throws子句声明抛出某种异常。例如,method3()方法调用了method1()方法,

method1()方法声明抛出IOException,因此,在method3()方法中可能会出现IOException。


---------------------------------------------------------------------------------------------------------------------------

注意:

1、Throw (是 catch 中还是非 catch 中)后面不能再跟其他代码块了 ,否则编译不能通过,

例如把return和throw放在一起,IDEA直接提示错误:"Unreachable statement" .

2、但可以在finally语句块有return语句,finally语句块成功骗过编译器让throw和return两者并存

finally如果有return会覆盖catch里的throw,同样如果finally里有throw会覆盖catch里的return。

进而如果catch里和finally都有return, finally中的return会覆盖catch中的。throw也是如此

 

posted @ 2021-08-06 21:06  zrswheart  阅读(37)  评论(0编辑  收藏  举报