1. 程式人生 > >java中finally與return的執行順序詳解

java中finally與return的執行順序詳解

一些準備知識:     首先為了說明白java中finally與return的執行順序是怎樣的這個問題,我們需要做一點準備工作。     java方法是在棧幀中執行,棧幀是執行緒私有棧的單位,執行方法的執行緒會為每一個方法分配一小塊棧空間來作為該方法執行時的記憶體空間,棧幀分為三個區域:     1. 運算元棧,用來儲存正在執行的表示式中的運算元,資料結構中學習過基於棧的多項式求值演算法,運算元棧的作用和這個一樣     2. 區域性變數區,用來儲存方法中使用的變數,包括方法引數,方法內部宣告的變數,以及方法中使用到的物件的成員變數或類的成員變數(靜態變數),最後兩種變數會複製到區域性變數區,因此在多執行緒          環境下,這種變數需要根據需要宣告為volatile型別
    3. 位元組碼指令區,這個不用解釋了,就是方法中的程式碼翻譯成的指令 return語句:     準備知識講完了,在本節中我們講解方法中沒有finally語句塊的情況下return語句的執行方式。現在我們先看看return語句,return語句的格式如下:     return [expression];     其中expression(表示式)是可選的,因為有些方法沒有返回值,所以return後面也就沒有表示式,或者可以看做是空的表示式。     我們知道return語句的作用可以結束方法並返回一個值,那麼他返回的是哪裡的值呢?返回的是return指令執行的時刻,運算元棧頂的值,不管expression是一個怎樣的表示式,究竟做了些什麼工作,對於return指令來說都不重要,他只負責把運算元棧頂的值返回。     而return expression是分成兩部分執行的:     執行:expression;     執行:return指令;     例如:return x+y;     這句程式碼先執行x+y,再執行return;首先執行將x以及y從區域性變數區複製到運算元棧頂的指令,然後執行加法指令,這個時候結果x+y的值會儲存在運算元棧的棧頂,最後執行return指令,返回運算元棧頂的值。     對於return x;先執行x,x也是一個表示式,這個表示式只有一個運算元,會執行將變數x從區域性變數區複製到運算元棧頂的指令,然後執行return,返回運算元棧頂的值。因此return x實際返回的是return指令執行時,x在運算元棧頂的一個快照或者叫副本,而不是x這個值。 finally語句塊:
    如果方法中有finally語句塊,那麼return語句又是如何執行的呢?     例如下面這段程式碼:     try{ return expression;   }finally{ do some work;   } 首先我們知道,finally語句是一定會執行,但他們的執行順序是怎麼樣的呢?他們的執行順序如下:     1、執行:expression,計算該表示式,結果儲存在運算元棧頂;     2、執行:運算元棧頂值(expression的結果)複製到區域性變數區作為返回值;     3、執行:finally語句塊中的程式碼;     4、執行:將第2步複製到區域性變數區的返回值又複製回運算元棧頂;
    5、執行:return指令,返回運算元棧頂的值;     我們可以看到,在第一步執行完畢後,整個方法的返回值就已經確定了,由於還要執行finally程式碼塊,因此程式會將返回值暫存在區域性變數區,騰出運算元棧用來執行finally語句塊中程式碼,等finally執行完畢,再將暫存的返回值又複製回運算元棧頂。所以無論finally語句塊中執行了什麼操作,都無法影響返回值,所以試圖在finally語句塊中修改返回值是徒勞的。因此,finally語句塊設計出來的目的只是為了讓方法執行一些重要的收尾工作,而不是用來計算返回值的。 如果還有不懂的話可以看看示例程式碼 public class FinallyDemo { public int testMethod(String _int,String _className){ int x = 1; try{ Integer.valueOf(_int); Class.forName(_className); //如果上面兩句程式碼沒有發生異常,對於return x這句程式碼,程式會先計算表示式x //即將x從區域性變數區複製到運算元棧頂,結果就是運算元棧頂的值,也就是x的值,為1 //然後將運算元棧頂的值複製到區域性變數區(假設這個複製到區域性變數區的值叫returnvalue),再執行finally程式碼塊,在finally程式碼塊 //中,x的值被修改為3(即區域性變數區中的x值),finally執行完,程式又將returnvalue複製到運算元棧頂,然後執行return指令,返回 //運算元棧頂的值,最終返回值是1 return x; }catch(ClassNotFoundException e){ //同樣發生了ClassNotFoundException,x的值被修改成2 //因此在catch中的return x語句中定義了返回值大小為2,所以最終返回的是2 x = 2; return x; }finally{ //這句程式碼一定會執行的,這裡的程式碼執行結束後才會結束方法並返回值,因此在finally語句修改x不會影響返回值,因為返回值在return 後面的 //表示式執行完就已經確定了,他是x的快照,而不是x x = 3; } } public static void main(String [] args){ try{ FinallyDemo demo = new FinallyDemo(); int i_1 = demo.testMethod("123123""expert.in.java.lang.CalendarDemo"); System.out.println(i_1);//結果為1 int i_2 = demo.testMethod("123123""com.edu.cn.qj.MyClass"); System.out.println(i_2);//結果為2 int i_3 = demo.testMethod("dsadf""expert.in.java.lang.CalendarDemo"); System.out.println(i_3);//沒有返回值,會丟擲異常 }finally{ } } }

相關推薦

javafinallyreturn執行順序

一些準備知識:     首先為了說明白java中finally與return的執行順序是怎樣的這個問題,我們需要做一點準備工作。     java方法是在棧幀中執行,棧幀是執行緒私有棧的單位,執行方法的執行緒會為每一個方法分配一小塊棧空間來作為該方法執行時的記憶體空間,棧幀

Javafinallyreturn執行順序

finally不會執行的兩種情況:1.finally對應的try塊語句還沒被執行到就返回了 2.finally對應的try塊語句中有System.exit()這樣的語句 finally塊的語句在tr

Java == 號equals()方法區別

== 號與equals()方法區別這個問題在面試中經常被問到,如果你瞭解的不透徹,很容易被問蒙。下面我們來一起看看吧。 1.基本資料型別,也稱原始資料型別。byte,short,char,int,long,float,double,boolean 他們之間的比較,應用雙等號(==)

Java類程式碼載入的順序

<span style="font-size:14px;">class GrandPa { public String grandpaName="grandpaName1"; //例項變數 public static int grandpaAge = 1; //靜態變數 //靜態程式碼塊

Java異常機制--try catch finally 執行順序

引言 關於try catch finally 執行順序的筆試面試題目非常的多,我曾經在牛客網刷題的時候不止一次的碰到過,而且不止一次的做錯過,這裡面需要涉及的細節如果不弄清楚每次做題就會產生似是而非的感覺。這次查閱了很多相關資料,關於try catch fin

javatry catch語句執行順序簡介

package com.string_lc; /** * @filename Test.java * @author l * @description */ public class Test { public static void main(String[] args) {

DQL執行順序

引言 這不是一個什麼多深的技術問題,多麼牛叉的程式設計能力。這跟一個人的開發能力也沒有非常必然的直接關係,但是知道這些會對你的SQL編寫,排憂及優化上會有很大的幫助。它不是一個複雜的知識點,但是一個非常基礎的SQL根基。不瞭解這些,你一直用普通水泥蓋

JAVA Breakreturn的區別

break是用來跳出迴圈的,例如for,while,do-while都可以跳出,但不跳出函式 return是使整個函式返回的,後面的不管是迴圈裡面還是迴圈外面的都不執行 再說一下,break語句通常用在迴圈語句和開關語句中,當break語句用於do-while、for、w

關於java switch 語句的執行順序

首先來一個正常的demo int i = 2; switch (i) { case 1: System.out.println("1"); break; case 2: System.out.println("2"); break;

Java技術_基礎技術(0003)_類執行順序+例項(阿里面試題)+詳細講解+流程圖

基礎技術: 對於java類各個成員的執行順序,現拿出阿里的面試題作為樣例(例子非常好,是用心出的題),在這裡重新說明一下java類執行順序的原則。 原始碼下載(包含題、結果、分析過程)

java類的執行順序、語句執行順序

本文講解Java中類的執行順序 順序應該是這樣的:父類Static->子類static->父類預設{}->父類建構函式->子類預設{}->子類建構函式 所以上面的例子列印順序應該是這樣的: parent static block 父類Stati

javafinalvolatile-執行緒安全問題

線上程安全問題中final主要體現在安全釋出問題上,在這裡先講一下什麼事安全釋出,在《java併發程式設計實踐》一書中有講,不過看起來挺難懂的…. public class Holder { private int n;

JS的async/await的執行順序

雖然大家知道async/await,但是很多人對這個方法中內部怎麼執行的還不是很瞭解,本文是我看了一遍技術部落格理解 JavaScript 的 async/await(如果對async/await不熟悉可以先看下http://es6.ruanyifeng.com/#docs/async)後拓展了一下,我理了一

HTTP協議報文、工作原理及Java的HTTP通信技術

tor 報文 buffered mod protoc 禁止 ans 請求報文 客戶端 博客園 首頁 新隨筆 聯系 管理 訂閱

javascript運行機制之執行順序

onload 預編譯 c# step 而且 () 我們 術語 aaa JavaScript是一種描述型腳本語言,它不同於java或C#等編譯性語言,它不需要進行編譯成中間語言,而是由瀏覽器進行動態地解析與執行。那麽JavaScript是怎麽來進行解析的嗎?它的執行順序又是如

JavaScriptSetIntervalsetTimeout的用法

sta 對象 show thead ansi out 計時 顯示 設計 在寫H5遊戲時經常需要使用定時刷新頁面實現動畫效果,比較常用即setTimeout()以及setInterval(),但是大家對SetInterval與setTimeout的用法了解嗎,下面通過

JavaList,Set和Map及其區別

內部 特殊 set contain 快速查找 簡單 rar dset 維護 Java中的集合包括三大類,它們是Set(集)、List(列表)和Map(映射),它們都處於java.util包中,Set、List和Map都是接口,它們有各自的實現類。Set的實現類主要有Hash

javaprivate,public,protected

轉載:https://blog.csdn.net/aimeimeits/article/details/54136219 訪問級別 訪問級別修飾符確定其他類是否可以使用特定欄位或呼叫特定方法。有兩個級別的訪問控制: 1.在頂級  - public或package-priva

Java物件的初始化過程

在Java中,我們需要對物件進行初始化操作。 經常需要new 物件。但是new物件時到底發生了什麼呢? 有時候我們不是特別清晰。 所以今天又重新學習了一下JavaSE部分,又有了新的感受。 在此記錄一下 首先程式碼部分 Person類: class Person{

Jqueryattrprop的區別

當點選左上方那個checkBox時,要將下面的checkBox全部選中,我們的程式碼是這樣的 $("input[name='checkbox']").attr("checked",true); 然並卵,一點效果都沒有,後來換成這樣,好了 $(function(){ $("#all").c