亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

finally與return之間的關(guān)系

Yuanf / 1363人閱讀

摘要:則會(huì)在轉(zhuǎn)移指令前執(zhí)行??偨Y(jié)與之間的關(guān)系如果在中含有語(yǔ)句,那么語(yǔ)句的還有作用嗎先看一段代碼如果你對(duì)內(nèi)存布局不是很清楚,請(qǐng)看這篇文章虛擬機(jī)類(lèi)加載機(jī)制和字節(jié)碼執(zhí)行引擎重點(diǎn)關(guān)注運(yùn)行時(shí)棧幀結(jié)構(gòu)局部變量表槽,操作數(shù)棧。

定論

問(wèn):finally語(yǔ)句一定會(huì)執(zhí)行嗎?
答:

如果沒(méi)有執(zhí)行相應(yīng)的try語(yǔ)句則不會(huì)執(zhí)行。

在try語(yǔ)句中如果調(diào)用System.exit(0)方法則不會(huì)執(zhí)行。

問(wèn):finally會(huì)在什么時(shí)候執(zhí)行?
答:如果在try/catch語(yǔ)句中調(diào)用轉(zhuǎn)移指令例如:return,break,continue,throw等。則會(huì)在轉(zhuǎn)移指令前執(zhí)行。

總結(jié) finally與return之間的關(guān)系

如果在finally中含有return語(yǔ)句,那么try/catch語(yǔ)句的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;
        }
    }
}

如果你對(duì)java內(nèi)存布局不是很清楚,請(qǐng)看這篇文章:java虛擬機(jī)類(lèi)加載機(jī)制和字節(jié)碼執(zhí)行引擎

重點(diǎn)關(guān)注運(yùn)行時(shí)棧幀結(jié)構(gòu)(局部變量表槽,操作數(shù)棧)。

上邊的代碼非常簡(jiǎn)單,來(lái)看一下字節(jié)碼指令吧

public static int test1();
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=3, args_size=0
         0: iconst_1        //定義一個(gè)常量1入棧到操作數(shù)棧            
         //棧1  0:  1:
         1: istore_0        //出棧,存儲(chǔ)到局部便量表槽0         
         //棧   0:1 1:
         2: iconst_2        //定義一個(gè)常量2入棧到操作數(shù)棧            
         //棧2  0:1 1:
         3: istore_0        //出棧,存儲(chǔ)到局部變量表槽0         
         //棧   0:2 1:
         4: iload_0        //從局部便量表槽0入棧到操作數(shù)棧   
         //棧2  0:2 1:
         5: istore_1        //出棧,存儲(chǔ)到局部變量表槽1         
         //棧   0:2 1:2
         6: iinc          0, 1 //局部變量表槽0變量加1               
         //棧   0:3 1:2
         9: iload_0        //從局部變量表槽0入棧到操作數(shù)棧   
         //棧3  0:3 1:2
        10: ireturn         //結(jié)束,返回                                 
        //棧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        //定義一個(gè)常量1入棧到操作數(shù)棧    
         //棧1  0:  1:
         1: istore_0        //出棧,存儲(chǔ)到局部便量表槽0 
         //棧   0:1 1:
         2: iconst_2        //定義一個(gè)常量2入棧到操作數(shù)棧    
         //棧2  0:1 1:
         3: istore_0        //出棧,存儲(chǔ)到局部變量表槽0 
         //棧   0:2 1:
         4: iload_0        //從局部變量表槽0入棧                
         //棧2  0:2 1:
         5: istore_1        //出棧,存儲(chǔ)到局部變量表槽1 
         //棧   0:2 1:2
         6: iconst_3        //定義一個(gè)常量3入棧                 
         //棧3  0:2 1:2
         7: istore_0        //出棧,存儲(chǔ)到局部便量表槽0 
         //棧   0:3 1:2
         8: iload_0        //從局部變量表槽0入棧                
         //棧3  0:3 1:2
         9: ireturn        //結(jié)束,返回                         
         //棧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        //定義一個(gè)常量1入棧到操作數(shù)棧    
         //棧1  0:  1:
         1: istore_0        //出棧,存儲(chǔ)到局部便量表槽0 
         //棧   0:1 1:
         2: iconst_2        //定義一個(gè)常量2入棧到操作數(shù)棧    
         //棧2  0:1 1:
         3: istore_0        //出棧,存儲(chǔ)到局部變量表槽0 
         //棧   0:2 1:
         4: iload_0        //從局部變量表槽0入棧                
         //棧2  0:2 1:
         5: istore_1        //出棧,存儲(chǔ)到局部變量表槽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         //結(jié)束,返回                         
        //棧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        //定義一個(gè)常量1入棧到操作數(shù)棧    
         //棧1  0:  1:
         1: istore_0        //出棧,存儲(chǔ)到局部便量表槽0 
         //棧   0:1 1:
         2: iconst_2        //定義一個(gè)常量2入棧到操作數(shù)棧    
         //棧2  0:1 1:
         3: istore_0        //出棧,存儲(chǔ)到局部變量表槽0 
         //棧   0:2 1:
         4: iload_0        //從局部變量表槽0入棧                
         //棧2  0:2 1:
         5: istore_1        //出棧,存儲(chǔ)到局部變量表槽1 
         //棧   0:2 1:2
         6: iconst_3        //定義一個(gè)常量3入棧到操作數(shù)棧    
         //棧3  0:2 1:2
         7: istore_0        //出棧,存儲(chǔ)到局部變量表槽0 
         //棧   0:3 1:2
         8: iload_1        //從局部變量表槽1入棧                
         //棧2  0:3 1:2
         9: ireturn        //結(jié)束,返回                         
         //棧2  0:3 1:2
        10: astore_2      
        11: iconst_3      
        12: istore_0      
        13: aload_2       
        14: athrow

我們看到:

在finally中沒(méi)有return時(shí),棧中最后存儲(chǔ)的數(shù)據(jù)是try/catch中操作后數(shù)據(jù)。即finally操作后的數(shù)據(jù)存儲(chǔ)到其他槽中,而后再加載try/catch操作后的數(shù)據(jù)。

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

也就是說(shuō):如果finally中不含有return語(yǔ)句,finally對(duì)try/catch操作的八大基礎(chǔ)類(lèi)型不會(huì)再加載到操作數(shù)棧中。

如果返回值是對(duì)象引用,finally中的return還有待考據(jù)。

參考:關(guān)于 Java 中 finally 語(yǔ)句塊的深度辨析
更多文章:http://blog.gavinzh.com

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/64459.html

相關(guān)文章

  • java內(nèi)存模型

    摘要:順序一致性?xún)?nèi)存模型有兩大特性一個(gè)線(xiàn)程中所有操作必須按照程序的順序執(zhí)行。這里的同步包括對(duì)常用同步原語(yǔ)的正確使用通過(guò)以下程序說(shuō)明與順序一致性?xún)煞N內(nèi)存模型的對(duì)比順序一致性模型中所有操作完全按程序的順序串行執(zhí)行。 java內(nèi)存模型 java內(nèi)存模型基礎(chǔ) happen-before模型 JSR-133使用happen-before的概念來(lái)闡述操作之間的內(nèi)存可見(jiàn)性。在JMM中,如果一個(gè)操作執(zhí)行的結(jié)...

    2i18ns 評(píng)論0 收藏0
  • 深入理解Java內(nèi)存模型(六)——final

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

    lixiang 評(píng)論0 收藏0
  • 聊聊Tomcat架構(gòu)設(shè)計(jì)

    摘要:本篇文章主要是跟大家聊聊的內(nèi)部架構(gòu)體系,讓大家對(duì)有個(gè)整體的認(rèn)知。方法會(huì)創(chuàng)建一個(gè)對(duì)象,調(diào)用它的方法將字節(jié)流封裝成對(duì)象,在創(chuàng)建組件時(shí),會(huì)將組件添加到組件中組件而組件在連接器初始化時(shí)就已經(jīng)創(chuàng)建好了目前為止,只有一個(gè)實(shí)現(xiàn)類(lèi),就是。 微信公眾號(hào)「后端進(jìn)階」,專(zhuān)注后端技術(shù)分享:Java、Golang、WEB框架、分布式中間件、服務(wù)治理等等。 老司機(jī)傾囊相授,帶你一路進(jìn)階,來(lái)不及解釋了快上車(chē)! T...

    cnio 評(píng)論0 收藏0
  • 《深入理解 Java 內(nèi)存模型》讀書(shū)筆記

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

    姘存按 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<