java finally在return_Java finally語句到底是在return之前還是之后執行?

點擊上方“方志朋”,選擇“置頂或者星標”

你的關注意義重大!

網上有很多人探討Java中異常捕獲機制try...catch...finally塊中的finally語句是不是一定會被執行?很多人都說不是,當然他們的回答是正確的,經過我試驗,至少有兩種情況下finally語句是不會被執行的:

try語句沒有被執行到,如在try語句之前就返回了,這樣finally語句就不會執行,這也說明了finally語句被執行的必要而非充分條件是:相應的try語句一定被執行到。

在try塊中有System.exit(0);這樣的語句,System.exit(0);是終止Java虛擬機JVM的,連JVM都停止了,所有都結束了,當然finally語句也不會被執行到。

當然還有很多人探討Finally語句的執行與return的關系,頗為讓人迷惑,不知道finally語句是在try的return之前執行還是之后執行?我也是一頭霧水,我覺得他們的說法都不正確,我覺得應該是:finally語句是在try的return語句執行之后,return返回之前執行。這樣的說法有點矛盾,也許是我表述不太清楚,下面我給出自己試驗的一些結果和示例進行佐證,有什么問題歡迎大家提出來。

finally語句在return語句執行之后return返回之前執行的。

publicclassFinallyTest1{

publicstaticvoidmain(String[] args) {

System.out.println(test1());

}

publicstaticinttest1() {

intb =20;

try{

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

returnb +=80;

}

catch(Exceptione) {

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

}

finally{

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

if(b >25) {

System.out.println("b>25, b = "+ b);

}

}

returnb;

}

}

運行結果是:

tryblock

finallyblock

b>25, b =100

100

說明return語句已經執行了再去執行finally語句,不過并沒有直接返回,而是等finally語句執行完了再返回結果。

如果覺得這個例子還不足以說明這個情況的話,下面再加個例子加強證明結論:

publicclassFinallyTest1{

publicstaticvoidmain(String[] args) {

System.out.println(test11());

}

publicstaticStringtest11() {

try{

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

returntest12();

}finally{

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

}

}

publicstaticStringtest12() {

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

return"after return";

}

}

運行結果為:

tryblock

returnstatement

finallyblock

afterreturn

說明try中的return語句先執行了但并沒有立即返回,等到finally執行結束后再

這里大家可能會想:如果finally里也有return語句,那么是不是就直接返回了,try中的return就不能返回了?看下面。

finally塊中的return語句會覆蓋try塊中的return返回。

publicclassFinallyTest2{

publicstaticvoidmain(String[] args) {

System.out.println(test2());

}

publicstaticinttest2() {

intb =20;

try{

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

returnb +=80;

}catch(Exceptione) {

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

}finally{

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

if(b >25) {

System.out.println("b>25, b = "+ b);

}

return200;

}

// return b;

}

}

運行結果是:

tryblock

finallyblock

b>25, b =100

200

這說明finally里的return直接返回了,就不管try中是否還有返回語句,這里還有個小細節需要注意,finally里加上return過后,finally外面的return b就變成不可到達語句了,也就是永遠不能被執行到,所以需要注釋掉否則編譯器報錯。

這里大家可能又想:如果finally里沒有return語句,但修改了b的值,那么try中return返回的是修改后的值還是原值?看下面。

如果finally語句中沒有return語句覆蓋返回值,那么原來的返回值可能因為finally里的修改而改變也可能不變。

測試用例1:

publicclassFinallyTest3{

publicstaticvoidmain(String[] args) {

System.out.println(test3());

}

publicstaticinttest3() {

intb =20;

try{

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

returnb +=80;

}catch(Exceptione) {

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

}finally{

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

if(b >25) {

System.out.println("b>25, b = "+ b);

}

b =150;

}

return2000;

}

}

運行結果是:

tryblock

finallyblock

b>25, b =100

100

測試用例2:

publicclassFinallyTest6

{

publicstaticvoidmain(String[] args) {

System.out.println(getMap().get("KEY").toString());

}

publicstaticMap getMap() {

Map map =newHashMap();

map.put("KEY","INIT");

try{

map.put("KEY","TRY");

returnmap;

}

catch(Exceptione) {

map.put("KEY","CATCH");

}

finally{

map.put("KEY","FINALLY");

map =null;

}

returnmap;

}

}

運行結果是:

FINALLY 為什么測試用例1中finally里的b = 150;并沒有起到作用而測試用例2中finally的map.put("KEY", "FINALLY");起了作用而map = null;卻沒起作用呢?這就是Java到底是傳值還是傳址的問題了,具體請看精選30道Java筆試題解答,里面有詳細的解答,簡單來說就是:Java中只有傳值沒有傳址,這也是為什么map = null這句不起作用。這同時也說明了返回語句是try中的return語句而不是 finally外面的return b;這句,不相信的話可以試下,將return b;改為return 294,對原來的結果沒有一點影響。

這里大家可能又要想:是不是每次返回的一定是try中的return語句呢?那么finally外的return b不是一點作用沒嗎?請看下面。

try塊里的return語句在異常的情況下不會被執行,這樣具體返回哪個看情況。

publicclassFinallyTest4{

publicstaticvoidmain(String[] args) {

System.out.println(test4());

}

publicstaticinttest4() {

intb =20;

try{

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

b = b /0;

returnb +=80;

}catch(Exceptione) {

b +=15;

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

}finally{

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

if(b >25) {

System.out.println("b>25, b = "+ b);

}

b +=50;

}

return204;

}

}

運行結果是:

tryblock

catchblock

finallyblock

b>25, b =35

85

這里因 為在return之前發生了除0異常,所以try中的return不會被執行到,而是接著執行捕獲異常的catch 語句和最終的finally語句,此時兩者對b的修改都影響了最終的返回值,這時return b;就起到作用了。當然如果你這里將return b改為return 300什么的,最后返回的就是300,這毋庸置疑。 這里大家可能又有疑問:如果catch中有return語句呢?當然只有在異常的情況下才有可能會執行,那么是在finally之前就返回嗎?看下面。

當發生異常后,catch中的return執行情況與未發生異常時try中return的執行情況完全一樣。

publicclassFinallyTest5{

publicstaticvoidmain(String[] args) {

System.out.println(test5());

}

publicstaticinttest5() {

intb =20;

try{

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

b = b /0;

returnb +=80;

}catch(Exceptione) {

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

returnb +=15;

}finally{

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

if(b >25) {

System.out.println("b>25, b = "+ b);

}

b +=50;

}

//return b;

}

}

運行結果如下:

tryblock

catchblock

finallyblock

b>25, b =35

35

說明了發生異常后,catch中的return語句先執行,確定了返回值后再去執行finally塊,執行完了catch再返回,finally里對b的改變對返回值無影響,原因同前面一樣,也就是說情況與try中的return語句執行完全一樣。

最后總結:finally塊的語句在try或catch中的return語句執行之后返回之前執行且finally里的修改語句可能影響也可能不影響try或catch中 return已經確定的返回值,若finally里也有return語句則覆蓋try或catch中的return語句直接返回。

原文鏈接:

https://www.cnblogs.com/lanxuezaipiao/p/3440471.html

-更多文章-

-關注我-

看完了,幫我點個“好看”鴨

點鴨點鴨

↓↓↓↓

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/388741.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/388741.shtml
英文地址,請注明出處:http://en.pswp.cn/news/388741.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

oracle 死鎖

為什么80%的碼農都做不了架構師?>>> ORA-01013: user requested cancel of current operation 轉載于:https://my.oschina.net/8808/blog/2994537

面試題:二叉樹的深度

題目描述:輸入一棵二叉樹,求該樹的深度。從根結點到葉結點依次經過的結點(含根、葉結點)形成樹的一條路徑,最長路徑的長度為樹的深度。 思路:遞歸 //遞歸 public class Solution {public int TreeDepth(Tre…

a/b測試_如何進行A / B測試?

a/b測試The idea of A/B testing is to present different content to different variants (user groups), gather their reactions and user behaviour and use the results to build product or marketing strategies in the future.A / B測試的想法是將不同的內容呈現給不同…

hibernate h2變mysql_struts2-hibernate-mysql開發案例 -解道Jdon

Hibernate專題struts2-hibernate-mysql開發案例與源碼源碼下載本案例展示使用Struts2,Hibernate和MySQL數據庫開發一個個人音樂管理器Web應用程序。,可將您的音樂收藏添加到數據庫中。功能有:顯示一個添加記錄的表單和所有的音樂收藏的列表。…

P5024 保衛王國

傳送門 我現在還是不明白為什么NOIPd2t3會是一道動態dp…… 首先關于動態dp可以看這里 然后這里就是把把矩陣給改一改,改成這個形式\[\left[dp_{i-1,0},dp_{i-1,1}\right]\times \left[\begin{matrix}\infty&ldp_{i,1}\\ldp_{i,0}&ldp_{i,1}\end{matrix}\ri…

提取圖像感興趣區域_從圖像中提取感興趣區域

提取圖像感興趣區域Welcome to the second post in this series where we talk about extracting regions of interest (ROI) from images using OpenCV and Python.歡迎來到本系列的第二篇文章,我們討論使用OpenCV和Python從圖像中提取感興趣區域(ROI)。 As a rec…

解決java compiler level does not match the version of the installed java project facet

ava compiler level does not match the version of the installed java project facet錯誤的解決 因工作的關系,Eclipse開發的Java項目拷來拷去,有時候會報一個很奇怪的錯誤。明明源碼一模一樣,為什么項目復制到另一臺機器上,就會…

php模板如何使用,ThinkPHP如何使用模板

到目前為止,我們只是使用了控制器和模型,還沒有接觸視圖,下面來給上面的應用添加視圖模板。首先我們修改下 Action 的 index 操作方法,添加模板賦值和渲染模板操作。PHP代碼classIndexActionextendsAction{publicfunctionindex(){…

理解Windows窗體和WPF中的跨線程調用

你曾開發過Windows窗體程序,可能會注意到有時事件處理程序將拋出InvalidOperationException異常,信息為“ 跨線程調用非法:在非創建控件的線程上訪問該控件”。這種Windows窗體應用程序中 跨線程調用時的一個最為奇怪的行為就是,有…

什么是嵌入式系統

在我們的日常生活中,我們經常使用許多使用嵌入式系統技術設計的電氣和電子電路和套件。計算機,手機,平板,筆記本電腦,數字電子系統以及其他電子和電子設備都是使用嵌入式系統設計的。 什么是嵌入式系統?將硬…

面向數據科學家的實用統計學_數據科學家必知的統計數據

面向數據科學家的實用統計學Beginners usually ignore most foundational statistical knowledge. To understand different models, and various techniques better, these concepts are essential. These work as baseline knowledge for various concepts involved in data …

字符串、指針、引用、數組基礎

1.字符串:字符是由單引號所括住的單個字母、數字或符號。若將單引號改為雙引號,該字符就會變成字符串。它們之間主要的差別是:雙引號的字符串“A”會比單引號的字符串’A’在字符串的最后補上一個結束符’\0’(Null字符&#xff0…

suse安裝php,SUSE下安裝LAMP

安裝Apache可以看到編譯安裝Apache出錯,rpm包安裝gcc (首先要安裝GCC)makemake install修改apache端口cd /home/sxit/apache2vi conf/httpd.confListen 8000啟動 apache/home/root/apache2/bin/apachectl start(stop restart)http://localhost:8000安裝一下PHP開發…

自己動手寫事件總線(EventBus)

2019獨角獸企業重金招聘Python工程師標準>>> 本文由云社區發表 事件總線核心邏輯的實現。 <!--more--> EventBus的作用 Android中存在各種通信場景&#xff0c;如Activity之間的跳轉&#xff0c;Activity與Fragment以及其他組件之間的交互&#xff0c;以及在某…

viz::viz3d報錯_我可以在Excel中獲得該Viz嗎?

viz::viz3d報錯Have you ever found yourself in the following situation?您是否遇到以下情況&#xff1f; Your team has been preparing and working tireless hours to create and showcase the end product — an interactive visual dashboard. It’s a culmination of…

php 數組合并字符,PHP將字符串或數組合并到一個數組內方法

本文主要和大家分享PHP將字符串或數組合并到一個數組內方法&#xff0c;有兩種方法&#xff0c;希望希望能幫助到大家。一般寫法&#xff1a;<?php /*** add a string or an array to another array** param array|string $val* param array $array*/function add_val_to_a…

xcode 4 最低的要求是 10.6.6的版本,如果你是 10.6.3的版本,又不想升級的話。可以考慮通過修改版本號的方法進行安裝

xcode 4 最低的要求是 10.6.6的版本&#xff0c;如果你是 10.6.3的版本&#xff0c;又不想升級的話。可以考慮通過修改版本號的方法進行安裝。 一、打開控制臺&#xff1b; 二、使用root用戶&#xff1b; 命令&#xff1a;sudo -s 之后輸入密碼即可 三、編輯 /System/Library/C…

android 調試技巧

1.查看當前堆棧 Call tree new Exception(“print trace”).printStackTrace(); &#xff08;在logcat中打印當前函數調用關系&#xff09; 2.MethodTracing 性能分析與優&#xff08; 函數占用CPU時間&#xff0c; 調用次數&#xff0c; 函數調用關系&#xff09; a) 在程序…

Xml序列化

xml序列化 實現思路 通過程序生成一個xml文件來備份手機短信. 先獲取手機短信的內容 —>通過xml備份.StringBuffer 代碼如下public void click(View view) {StringBuffer sb new StringBuffer();sb.append("<?xml version\"1.0\" encoding\"UTF-8\…

java 添加用戶 數據庫,跟屌絲學DB2 第二課 建立數據庫以及添加用戶

在安裝DB2 之后&#xff0c;就可以在 DB2 環境中創建自己的數據庫。首先考慮數據庫應該使用哪個實例。實例(instance) 提供一個由數據庫管理配置(DBM CFG)文件控制的邏輯層&#xff0c;可以在這里將多個數據庫分組在一起。DBM CFG 文件包含一組 DBM CFG 參數&#xff0c;可以使…