朝花夕拾——finally/final/finalize拨云雾见青天
生活随笔
收集整理的這篇文章主要介紹了
朝花夕拾——finally/final/finalize拨云雾见青天
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
Java編程中。常常會使用到異常處理,而finally看似的是try/catch后對邏輯處理的完好,事實上里面卻存在非常多隱晦的陷阱。final常見于變量修飾,那么你在內(nèi)部類中也見過吧。finalize作為GC回收對象前的一道門,什么時候運行。運行效果又是如何。有時看看又忘了。以下是我總結(jié)網(wǎng)上朋友的一些博文及其帖子對三者進行總結(jié)。(重點講下finally)
先看final
- Final修飾變量不能被又一次賦值,其修飾實例變量時,定義時指定值則可視為“宏變量”。在非靜態(tài)代碼塊和構(gòu)造器中初始化值則不是。其修飾類變量時。僅僅有在定義時指定值才視為“宏變量”,在靜態(tài)代碼塊中初始化則不是。
- Final修飾的方法不能被重寫
- Final修飾的類不能被繼承
- 內(nèi)部類一般使用final修飾的局部變量。
在看finalize
- 系統(tǒng)調(diào)用finalize方法具有不確定性
- finalize方法是protected方法。子類能夠覆蓋該方法以實現(xiàn)資源清理工作,GC在回收對象之前調(diào)用該方法。一般當(dāng)對象在變成不可到達的時候,GC會推斷是否覆蓋該方法,假設(shè)沒有覆蓋就直接回收。假設(shè)覆蓋就把該對象放進F-Queue隊列并由一低優(yōu)先級線程運行該對象的finalize方法,然后再次推斷是否可達。
- 盡量不要去調(diào)用finalize,假設(shè)調(diào)用。則避免對象再生,多用于關(guān)閉流。
最后細斟finally
- Finall語句在return語句運行之后,return返回之前運行;
- Finally塊中的return語句運行結(jié)果覆蓋try和catch中運行的return語句運行結(jié)果
- Finally塊中操作try/catch返回基本變量時。結(jié)果不受finally操作影響
- Finally塊中操作try/catch返回引用對象時。
結(jié)果受finally操作影響
樣例1代碼例如以下: package java_zhaohuaxishi;public class Example1 {public int test(){int i = 0; try{i = 10;System.out.println("try");return i+=10;}catch(Exception e){i = 20;return 200;}finally{System.out.println("finally");System.out.println(i);}}/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stubSystem.out.println(new Example1().test());}} 執(zhí)行結(jié)果: try finally 20 20 這也意味著finally打印出來的是try中return已經(jīng)計算了的,驗證觀點一。
樣例2代碼例如以下: package java_zhaohuaxishi;public class Example1 {public int test(){int i = 0; try{i = 10;return 100;}catch(Exception e){i = 20;return 200;}finally{return i;}}/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stubSystem.out.println(new Example1().test());}} 上述時沒有出現(xiàn)異常情況,打印例如以下: 10
再給出出現(xiàn)異常情況,代碼例如以下: package java_zhaohuaxishi;public class Example2 {public int test(){int i = 0; try{i = 10/0;return 100;}catch(Exception e){i = 20;return 200;}finally{return i;}}/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stubSystem.out.println(new Example2().test());}} 打印結(jié)果例如以下: 20結(jié)果是:不管出現(xiàn)異常與否,finally的return總會覆蓋try/catch中return的結(jié)果。驗證觀點二。
樣例3代碼例如以下: package java_zhaohuaxishi;public class Example5 {public int test(){int i = 0; try{i = 10;return i; }catch(Exception e){i = 20;return i; }finally{i=30;//return i;} }/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stubSystem.out.println(new Example5().test());} } 打印結(jié)果例如以下: 10能夠看到。實際上finally改動i變量是不起作用的。驗證觀點三。
樣例4代碼例如以下: package java_zhaohuaxishi;class Test{int num;public Test(int num){this.num = num; }public int getNum() {return num;}public void setNum(int num) {this.num = num;}}public class Example3 {public Test test(){ Test t = new Test(0); try{t.setNum(10);return t;}catch(Exception e){t.setNum(20);return t;}finally{t.setNum(30);}}/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stubSystem.out.println(new Example3().test().getNum());}} 打印結(jié)果例如以下: 30 從上述結(jié)果來看,finally操作的對象確實是與try上的同一個對象。那么我們比較上面觀點三,操作變量的時候是不能更改的,想想有點詭異。我們看以下代碼: package java_zhaohuaxishi;class Test{int num; public Test(int num){this.num = num; }public int getNum() {return num;}public void setNum(int num) {this.num = num;}}public class Example3 {public int test(){Test t = new Test(0);try{t.setNum(10);System.out.println(t.getNum());return t.getNum();}catch(Exception e){t.setNum(20);return t.getNum();}finally{System.out.println(t.getNum());t.setNum(30);}}/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stubSystem.out.println(new Example3().test());}} 這次我們不在返回對象。而是返回一個int變量。從觀點一我們能夠知道,返回的t.getNum()實際上是會先計算再保存起來。那么假設(shè)我們在finally中在去改變t的num,實際上t的num會被改變,然而返回的應(yīng)該還是10。 打印結(jié)果例如以下: 10 30 10 果然!這與我們預(yù)先的是一模一樣。假設(shè)有人認為finally中t對象可能與try中不一致。以下樣例將會讓你認為非常奇妙: package java_zhaohuaxishi;class Test4{int num;public Test4(int num){this.num = num; }public int getNum() {return num;}public void setNum(int num) {this.num = num;}}public class Example4 {public Test4 test(Test4 t){ System.out.println("傳進去的t:"+t.hashCode());try{t.setNum(10);return t;}catch(Exception e){t.setNum(20);return t;}finally{//t.setNum(30);System.out.println("finally改動前:"+t.hashCode());t = new Test4(0);System.out.println("finally改動后:"+t.hashCode());//return t;}}/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stubTest4 t = new Test4(0);System.out.println("return返回對象"+new Example4().test(t).hashCode());System.out.println("最后的t:"+t.hashCode());}} 我們來看看打印結(jié)果: 傳進去的t:2004703190 finally改動前:2004703190 finally改動后:1175576547 return返回對象2004703190 最后的t:2004703190這結(jié)果看起來非常奇妙。我們驗證觀點四的時候操作對象是起作用的!然而當(dāng)我們試圖去改動t引用讓他指向其它對象的時候居然無效......
如有很多其它興趣深入了解。可進一步認識JVM工作機制!
轉(zhuǎn)載于:https://www.cnblogs.com/blfbuaa/p/6915692.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的朝花夕拾——finally/final/finalize拨云雾见青天的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言windows停止工作,win7系
- 下一篇: 用户空间访问I2C设备驱动