try、catch、throw、throws、finally详解

一.关键字:throw,throws,try和catch的用法如下:

1、throws出现在方法的声明中,表示该方法可能会抛出的异常,允许throws后面跟着多个异常类型

2、throw出现在方法体中,用于抛出异常。当方法在执行过程中遇到异常情况时,将异常信息封装为异常对象,然后throw,告知用户。

3、try出现在方法体中,它自身是一个代码块,表示尝试执行代码块的语句。如果在执行过程中有某条语句抛出异常,那么代码块后面的语句将不被执行。

4、catch出现在try代码块的后面,自身也是一个代码块,用于捕获异常try代码块中可能抛出的异常。catch关键字后面紧接着它能捕获的异常类型,所有异常类型的子类异常也能被捕获。

二.为什么要使用 finally

1.假设 count 为需要使用的资源并且使用完之后需要释放资源,那么 我们可以吧释放资源的语句放到 try-catch后执行,当前程序不管执不执行try-catch语句,都会执行释放资源的语句

//初始化资源
int count = 0 ;

try{


count ++ ;

if(count==1)throw new Exception ("Exception in try");


}catch(Exception e){


System.out.println("catch block");

}

//释放资源

count = 0;

2.但是当 try 或catch 中有多条 return 语句,那么每次 return 之前,都需要执行释放资源的语句

public void f() throws Exception {

int count = 0;  //初始化资源

try{

   doSomething;

   statementMayCauseException;  //可能会抛出异常的语句,若异常没有被catch,则直接抛出,也不会执行到try-catch下面的语句

   doSomething;

   if(count == 1) throw new Exception1("E1 in try");

    if(count == 2) throw new Exception2("E2 in try");

}catch(Exception1 e){

   

count = 0; //释放资源

    throw e;  //再次把异常抛出,让上一级捕获。此时将不会执行catch外的语句,所以要先释放资源



}catch(Exception2 e){



count = 0; //释放资源

return; //返回了,也不会执行catch外的语句,所以要先释放资源

}

count = 0; //释放资源

}

3.这样,就需要在每一个可能返回的地方,以及每一个可能出现异常而导致程序跳转的地方,考虑如何释放资源,导致复杂和冗余。

所以,需要finally语句。

把资源释放或状态还原的代码放到finally块中,可以保证在try和catch语句执行完后,一定会执行finally语句块,而不用考虑各种复杂的跳转情况。

int count = 0;

try{

count++;

if(count == 1)throw new Exception();

}catch(Exception e){

}finally{

count = 0;

}

4.finally什么时候执行

finally在return语句之后,跳转到上一级程序之前执行。

public class Test { 

public static void main(String[] args) {  

System.out .println(test ());  

}   

public static String test() {  

try {  

System.out .println("try block");  

return test1 ();  

} finally {  

System.out .println("finally block");

 //return "finally";   若打开,则替换"after return" 

}  

}  

public static String test1() {  

System.out .println("return statement");  

 return "after return";  

}  

}

结果:

try block

return statement

finally block

after return

分析:

1.try语句块,return test1(),则调用test1方法

2.test1()执行后返回"after return",返回值"after return"保存在一个临时区域里

3.执行finally语句块。若finally语句有返回值,则此返回值将替换掉临时区域的返回值

4.将临时区域的返回值送到上一级方法中。

如果若finally语句有返回值,则此返回值将替换掉临时区域的返回值

 

5.验证finally真正执行顺序

package test;

import java.io.*;

public class Test1{

public static void main(String argv[]){

     Test1 m=new Test1();

     System.out.println(m.amethod());

 }

public int amethod(){

       try{

            FileInputStream dis =new FileInputStream("Hello.txt"); //1,抛出异常

        }catch ( Exception ex) {

               System.out.println("No such file found");   //2.catch捕获异常,并执行

               return -1;                                  //4,return 返回

        }finally{

               System.out.println("Doing finally");  //3.finally一定会执行,在return之前。(准确说,应该是return ;语句)

       }

         return 0;

    }

  }

    输出结果为:

    No such file found

    Doing finally

    -1

总结:finally其实是仅在return ; 语句执行前执行,如果return 一个函数,那么会先执行函数,但如果函数内有(return ;)语句,那么finally就会在这个(return ;)语句前执行。

ps:如果catch块有异常向外抛出,执行顺序呢:我执行说,你抛你得异常,我finally我的语句,我俩互不干涉,你别管我啥时执行,但我一定会执行。

关于finally,此时,应该很明朗了  您只需记着一点:除非调用system.exit()让程序退出或断电等因素致使程序中止,否则,无论任何因素,finally块都一定会执行!!

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值