国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

finally與return之間的關系

Yuanf / 1291人閱讀

摘要:則會在轉移指令前執行。總結與之間的關系如果在中含有語句,那么語句的還有作用嗎先看一段代碼如果你對內存布局不是很清楚,請看這篇文章虛擬機類加載機制和字節碼執行引擎重點關注運行時棧幀結構局部變量表槽,操作數棧。

定論

問:finally語句一定會執行嗎?
答:

如果沒有執行相應的try語句則不會執行。

在try語句中如果調用System.exit(0)方法則不會執行。

問:finally會在什么時候執行?
答:如果在try/catch語句中調用轉移指令例如:return,break,continue,throw等。則會在轉移指令前執行。

總結 finally與return之間的關系

如果在finally中含有return語句,那么try/catch語句的return還有作用嗎?

先看一段代碼:

/**
 * Created by gavin on 15-9-2.
 */
public class FinallyTest {
    public static void main(String[] args){
        System.out.println(test1());    //3
        System.out.println(test2());    //3
        System.out.println(test3());    //2
        System.out.println(test4());    //2
    }
    public static int test1()
    {
        int i = 1;
        try {
            i = 2;
            return i;
        }finally {
            i++;
            return i;
        }
    }
    public static int test2()
    {
        int i = 1;
        try {
            i = 2;
            return i;
        }finally {
            i = 3;
            return i;
        }
    }
    public static int test3()
    {
        int i = 1;
        try {
            i = 2;
            return i;
        }finally {
            i++;
        }
    }
    public static int test4()
    {
        int i = 1;
        try {
            i = 2;
            return i;
        }finally {
            i = 3;
        }
    }
}

如果你對java內存布局不是很清楚,請看這篇文章:java虛擬機類加載機制和字節碼執行引擎

重點關注運行時棧幀結構(局部變量表槽操作數棧)。

上邊的代碼非常簡單,來看一下字節碼指令吧

public static int test1();
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=3, args_size=0
         0: iconst_1        //定義一個常量1入棧到操作數棧            
         //棧1  0:  1:
         1: istore_0        //出棧,存儲到局部便量表槽0         
         //棧   0:1 1:
         2: iconst_2        //定義一個常量2入棧到操作數棧            
         //棧2  0:1 1:
         3: istore_0        //出棧,存儲到局部變量表槽0         
         //棧   0:2 1:
         4: iload_0        //從局部便量表槽0入棧到操作數棧   
         //棧2  0:2 1:
         5: istore_1        //出棧,存儲到局部變量表槽1         
         //棧   0:2 1:2
         6: iinc          0, 1 //局部變量表槽0變量加1               
         //棧   0:3 1:2
         9: iload_0        //從局部變量表槽0入棧到操作數棧   
         //棧3  0:3 1:2
        10: ireturn         //結束,返回                                 
        //棧3   0:3 1:2
        11: astore_2      
        12: iinc          0, 1
        15: iload_0       
        16: ireturn       
   
  public static int test2();
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=3, args_size=0
         0: iconst_1        //定義一個常量1入棧到操作數棧    
         //棧1  0:  1:
         1: istore_0        //出棧,存儲到局部便量表槽0 
         //棧   0:1 1:
         2: iconst_2        //定義一個常量2入棧到操作數棧    
         //棧2  0:1 1:
         3: istore_0        //出棧,存儲到局部變量表槽0 
         //棧   0:2 1:
         4: iload_0        //從局部變量表槽0入棧                
         //棧2  0:2 1:
         5: istore_1        //出棧,存儲到局部變量表槽1 
         //棧   0:2 1:2
         6: iconst_3        //定義一個常量3入棧                 
         //棧3  0:2 1:2
         7: istore_0        //出棧,存儲到局部便量表槽0 
         //棧   0:3 1:2
         8: iload_0        //從局部變量表槽0入棧                
         //棧3  0:3 1:2
         9: ireturn        //結束,返回                         
         //棧3  0:3 1:2
        10: astore_2         
        11: iconst_3      
        12: istore_0      
        13: iload_0       
        14: ireturn       
    
  public static int test3();
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=3, args_size=0
         0: iconst_1        //定義一個常量1入棧到操作數棧    
         //棧1  0:  1:
         1: istore_0        //出棧,存儲到局部便量表槽0 
         //棧   0:1 1:
         2: iconst_2        //定義一個常量2入棧到操作數棧    
         //棧2  0:1 1:
         3: istore_0        //出棧,存儲到局部變量表槽0 
         //棧   0:2 1:
         4: iload_0        //從局部變量表槽0入棧                
         //棧2  0:2 1:
         5: istore_1        //出棧,存儲到局部變量表槽1 
         //棧   0:2 1:2
         6: iinc          0, 1 //局部變量表槽0變量加一       
         //棧   0:3 1:2
         9: iload_1        //從局部變量表槽1入棧                
         //棧2  0:3 1:2
        10: ireturn         //結束,返回                         
        //棧2   0:3 1:2
        11: astore_2      
        12: iinc          0, 1
        15: aload_2       
        16: athrow        
   
  public static int test4();
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=3, args_size=0
         0: iconst_1        //定義一個常量1入棧到操作數棧    
         //棧1  0:  1:
         1: istore_0        //出棧,存儲到局部便量表槽0 
         //棧   0:1 1:
         2: iconst_2        //定義一個常量2入棧到操作數棧    
         //棧2  0:1 1:
         3: istore_0        //出棧,存儲到局部變量表槽0 
         //棧   0:2 1:
         4: iload_0        //從局部變量表槽0入棧                
         //棧2  0:2 1:
         5: istore_1        //出棧,存儲到局部變量表槽1 
         //棧   0:2 1:2
         6: iconst_3        //定義一個常量3入棧到操作數棧    
         //棧3  0:2 1:2
         7: istore_0        //出棧,存儲到局部變量表槽0 
         //棧   0:3 1:2
         8: iload_1        //從局部變量表槽1入棧                
         //棧2  0:3 1:2
         9: ireturn        //結束,返回                         
         //棧2  0:3 1:2
        10: astore_2      
        11: iconst_3      
        12: istore_0      
        13: aload_2       
        14: athrow

我們看到:

在finally中沒有return時,棧中最后存儲的數據是try/catch中操作后數據。即finally操作后的數據存儲到其他槽中,而后再加載try/catch操作后的數據。

而在finally中含有return時,棧中最后存儲的數據是finally中操作后的數據。即finally操作后的數據存儲到其他槽中,而后加載的是其他槽(finally)中的數據。

也就是說:如果finally中不含有return語句,finally對try/catch操作的八大基礎類型不會再加載到操作數棧中。

如果返回值是對象引用,finally中的return還有待考據。

參考:關于 Java 中 finally 語句塊的深度辨析
更多文章:http://blog.gavinzh.com

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/64459.html

相關文章

  • java內存模型

    摘要:順序一致性內存模型有兩大特性一個線程中所有操作必須按照程序的順序執行。這里的同步包括對常用同步原語的正確使用通過以下程序說明與順序一致性兩種內存模型的對比順序一致性模型中所有操作完全按程序的順序串行執行。 java內存模型 java內存模型基礎 happen-before模型 JSR-133使用happen-before的概念來闡述操作之間的內存可見性。在JMM中,如果一個操作執行的結...

    2i18ns 評論0 收藏0
  • 深入理解Java內存模型(六)——final

    摘要:對于域,編譯器和處理器要遵守兩個重排序規則在構造函數內對一個域的寫入,與隨后把這個被構造對象的引用賦值給一個引用變量,這兩個操作之間不能重排序。這個屏障禁止處理器把域的寫重排序到構造函數之外。下一篇深入理解內存模型七總結 與前面介紹的鎖和volatile相比較,對final域的讀和寫更像是普通的變量訪問。對于final域,編譯器和處理器要遵守兩個重排序規則: 在構造函數內對一個fi...

    lixiang 評論0 收藏0
  • 聊聊Tomcat架構設計

    摘要:本篇文章主要是跟大家聊聊的內部架構體系,讓大家對有個整體的認知。方法會創建一個對象,調用它的方法將字節流封裝成對象,在創建組件時,會將組件添加到組件中組件而組件在連接器初始化時就已經創建好了目前為止,只有一個實現類,就是。 微信公眾號「后端進階」,專注后端技術分享:Java、Golang、WEB框架、分布式中間件、服務治理等等。 老司機傾囊相授,帶你一路進階,來不及解釋了快上車! T...

    cnio 評論0 收藏0
  • 《深入理解 Java 內存模型》讀書筆記

    摘要:前提深入理解內存模型程曉明著,該書在以前看過一遍,現在學的東西越多,感覺那塊越重要,于是又再細看一遍,于是便有了下面的讀書筆記總結。同步同步是指程序用于控制不同線程之間操作發生相對順序的機制。線程之間的通信由內存模型控制。 showImg(https://mmbiz.qpic.cn/mmbiz_jpg/1flHOHZw6RtPu3BNx3zps1JhSmPICRw7QgeOmxOfTb...

    姘存按 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<