前言
這篇速讀文章來自面試的常客final、finally、finalize。說實話不大很理解為啥很多面試官喜歡把這三者放在一起。這完全不相干啊!不過既來之則安之吧。
今天讓我們聊一聊final、finally、finalize各自的場景。
正題
引子
小A:MDove,我最近發現很多文章會把final、finally、finalize放在一起比較。恕我愚鈍,我實在不知道它們有什麼關係。
MDove:它們的關係你竟然看不出來?這不就是:這三者就是卡巴斯基、巴基斯坦和小丑巴基的關係,有個基巴關係!
小A:啊?……
final
MDove:對於我們來說final是很基礎的關鍵字。final可以用來修飾類、方法、變量。
1、final修飾的class,代表不可以繼承擴展。2、final的方法也是不可以重寫的。3、final修飾的變量是不可以修改的。MDove:咱們重點提一提第3點,這裡所謂的不可修改對於基本類型來來,的確是不可以修改。而對於引用類型來說,只能說不能重新賦值。也就是不能改變引用地址。但是作為引用類型,它內部所包含的內容如果不是final則可以隨意修改咯,就像:
final List<string> arryList = new ArrayList<>();
arryList.add("AAA");
arryList.add("BBB");
List<string> unmodifiableArrayList = List.of("AAA", "BBB");
unmodifiableArrayList.add("CCC");
/<string>/<string>
MDove
MDove:我們都知道final聲明的變量需要顯示的給它賦初始值的。這裡考考你,如果不想直接給它賦值,那應該怎麼做?
小A:我猜…需要在構造方法裡邊吧?
MDove:沒錯的確是這樣:
fianl int num;
final int num2 = 666;
public Test(){
num = 666;
}
MDove:前面的文章,我們有提到其實這倆種寫法,對於編譯的class文件是等價的。
MDove:關於final,還有個有趣的地方。在很多文章中,會提到在特定場景下final能夠提高性能。比如:利用final可能有助於JVM將方法進行內聯,可以改善編譯器進行條件編譯的能力等等。說實話這種假設完全沒有考慮的必要。
finally
MDove:接下來讓我們來聊一聊finally。提到finally,那麼try-catch就逃不掉了。finally 則是Java保證重點代碼一定要被執行的一種機制。最常用的地方:通過try-catch-finally來進行類似資源釋放、保證解鎖等動作。比如:
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(new File("test"));
System.out.println(inputStream.read());
} catch (IOException e) {
throw new RuntimeException(e.getMessage(), e);
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
}
MDove:這裡提一點,try-finally也是可以的。不過這裡個人不建議省略掉catch。因為前一段時間我們就踩到了這個坑。我們項目裡捕獲的異常,一般都會在catch裡通過Error的CallBack傳出去,打Log。那次我們在追一個Bug的時候,發現竟然什麼Log都沒有。後來才發現,出Bug的地方,try異常後沒有做任何處理直接finally,導致沒有辦法看到Log日誌,浪費了很多時間。
try (FileInputStream inputStream = new FileInputStream(new File("test"))) {
System.out.println(inputStream.read());
} catch (IOException e) {
throw new RuntimeException(e.getMessage(), e);
}
這二者的寫法是等價的。當然這只是一種語法糖~
MDove:當然有些喪心病狂的題目,會問你什麼情況下finally不執行。這種情況就不執行了:
try {
System.exit(1);
} finally{
System.out.println(“程序都死了,我還執行個毛線~”);
}
MDove:可以看出,能導致程序停止的操作,finally都沒辦法執行了。說實話這真的沒有啥意義…
MDove:最後我們來聊一聊finalize。
finalize
MDove
MDove:關於finalize說白了,它設計之初的作用就是:在CG要回收某個對象時,讓這個對象有底氣的大喊一聲:“報告,我還能再搶救一下!”。但是也正是因為如此,JVM要對它進行額外處理。finalize也就成為了CG回收的阻礙者,也就會導致這個對象經過多個垃圾收集週期才能被回收。
MDove:因為我自己對finalize瞭解也不是很深,所以關於finalize的內容就暫時讓我們止步於此。如果你還是感興趣,可以搜一搜相關的分析文章。
MDove:不知道一路捋到這,你是不是多少對這三者有了一些瞭解。實話實說,他們三者瞭解瞭解就完OJBK了,知道它們設計的初衷,瞭解它們的用法。可以靈活多變的應用到業務中就哦了。過分的追求一些“奇技淫巧”,反而失去了設計本身的意義。
小A:真是學無止境,我覺得我好想選錯了行業。