1.当Java程序执行try块、catch块时遇到return语句,return语句会导致该方法立即结束。系统执行完return语句之后,并不会立即结束该方法,而是去寻找该异常处理流程中是否包含finally块,若没有finally块,则方法终止,返回相应的返回值;


若有finally块,则立即开始执行finally块,此时若finally块中没有return语句,则系统才会再次跳回来根据try块或catch块中的return语句结束方法(但是,不会再次执行return语句体,还是第一次执行的那个结果);若finally块中有return语句,则finally块已经结束了方法,系统不会跳回去执行try块或catch块里的任何代码。


没有finally块的比较简单,这里只看有finally块的,看如下代码:


[java] view plaincopy


package com.mys.test;  

  

public class Test {  

  

    /** 

     * @param args 

     */  

    public static void main(String[] args) {  

        Test test = new Test();  

        int a = 0;  

        try {  

            a = test.test();  

        } catch (Exception e) {  

            // TODO Auto-generated catch block  

            e.printStackTrace();  

        }  

        System.out.println("调用test()后a="+a);  

          

    }  

  

    @SuppressWarnings("finally")  

    private int test()throws Exception {  

        int count = 5;  

        try{  

            System.out.println("try块,count="+count);  

            return ++count;//main()中输出6  

//          return count++;//main()中输出5  

        }finally{  

            count=100000;  

            System.out.println("finally块,count++="+count++ +"  ,count="+count);  

        }  

    }  

  

}  

第一种finally块中没有return语句,则上面代码输入如下:

try块,count=5

finally块,count++=100000  ,count=100001

调用test()后a=6


其中调用test()后a=6就说明了执行完finally块后代码虽然立刻返回了,但不会再次执行try或catch块中的return语句体,还是第一次执行的那个结果(由局部变量决定的)


[java] view plaincopy


<span style="color:#333333;">package com.mys.test;  

  

public class Test {  

  

    /** 

     * @param args 

     */  

    public static void main(String[] args) {  

        Test test = new Test();  

        int a = 0;  

        try {  

            a = test.test();  

        } catch (Exception e) {  

            // TODO Auto-generated catch block  

            e.printStackTrace();  

        }  

        System.out.println("调用test()后a="+a);  

          

    }  

  

    @SuppressWarnings("finally")  

    private int test()throws Exception {  

        int count = 5;  

        try{  

            System.out.println("try块,count="+count);  

            return ++count;  

        }finally{  

            count=100000;  

            System.out.println("finally块,count++="+count++ +"  ,count="+count);  

            return ++count;  

        }  

    }  

  

}</span>  

第二种finally块中有return语句,则上面代码输入如下:

try块,count=5

finally块,count++=100000  ,count=100001

调用test()后a=100002




2.再来看另一种情况,


[java] view plaincopy


package com.mys.test;  

  

public class Test {  

  

    /** 

     * @param args 

     */  

    public static void main(String[] args) {  

        Test test = new Test();  

        int a = 0;  

        try {  

            a = test.test();  

        } catch (Exception e) {  

            // TODO Auto-generated catch block  

            e.printStackTrace();  

        }  

        System.out.println("调用test()后a="+a);  

          

    }  

  

    @SuppressWarnings("finally")  

    private int test(){  

        int count = 5;  

        try{  

            System.out.println("try块,count="+count);  

            throw new RuntimeException("测试异常");  

        }finally{  

            count=100000;  

            System.out.println("finally块,count++="+count++ +"  ,count="+count);  

            return ++count;  

        }  

    }  

  

}  

上面代码输入如下:

try块,count=5

finally块,count++=100000  ,count=100001

调用test()后a=100002

try块中抛出了RuntimeException异常,同时程序中并未使用catch块来捕获这个异常,正常情况下,该异常应导致test()方法非正常终止,test()应该没有返回值。但实际情况是,test()完全可以正常结束.这也符合finally块执行的流程:


当程序执行try块、catch块时遇到throw语句,throw语句会导致该方法立即结束。系统执行完throw语句之后,并不会立即结束该方法,而是去寻找该异常处理流程中是否包含finally块,若没有finally块,则程序立即抛出异常;


若有finally块,则立即开始执行finally块,此时若finally块中没有return语句,则系统才会再次跳回来抛出异常;若finally块中有return语句,则finally块已经结束了方法,系统不会跳回去执行try块或catch块去抛出异常。


由于上面的例子是使用的RuntimeException异常,该异常属于非受查异常,编译器不要求强制处置的异常

(强制处理的需要用try...catch...或者往上抛出(test() throws Exception),所以,能够正常输出.


即没有异常,如果,把 上例中finally块中的return ++count;去掉就会抛出异常了!!!