1. 程式人生 > >java基礎之final, finally, finalize 的區別

java基礎之final, finally, finalize 的區別

final

在java中,final可以用來修飾類,方法和變數(成員變數或區域性變數)。

1.1 修飾類

當用final修飾類的時,表明該類不能被其他類所繼承。當我們需要讓一個類永遠不被繼承,此時就可以用final修飾,但要注意:

final類中所有的成員方法都會隱式的定義為final方法 1.2 修飾方法 若父類中final方法的訪問許可權為private,將導致子類中不能直接繼承該方法,因此,此時可以在子類中定義相同方法名的函式,此時不會與重寫final的矛盾,而是在子類中重新地定義了新方法

1.3修飾變數 final成員變量表示常量,只能被賦值一次,賦值後其值不再改變。類似於C++中的const。

當final修飾一個基本資料型別時,表示該基本資料型別的值一旦在初始化後便不能發生變化;如果final修飾一個引用型別時,則在對其初始化之後便不能再讓其指向其他物件了,但該引用所指向的物件的內容是可以發生變化的。本質上是一回事,因為引用的值是一個地址,final要求值,即地址的值不發生變化。    final修飾一個成員變數(屬性),必須要顯示初始化。這裡有兩種初始化方式,一種是在變數宣告的時候初始化;第二種方法是在宣告變數的時候不賦初值,但是要在這個變數所在的類的所有的建構函式中對這個變數賦初值。   當函式的引數型別宣告為final時,說明該引數是隻讀型的。即你可以讀取使用該引數,但是無法改變該引數的值

在java中,String被設計成final類,那為什麼平時使用時,String的值可以被改變呢?

字串常量池是java堆記憶體中一個特殊的儲存區域,當我們建立一個String物件時,假設常量池不存在該字串,則建立一個,若存在則直接引用已經存在的字串。當我們對String物件值改變的時候,例如 String a=“A”; a=“B” 。a是String物件的一個引用(我們這裡所說的String物件其實是指字串常量),當a=“B”執行時,並不是原本String物件(“A”)發生改變,而是建立一個新的物件(“B”),令a引用它

2. finally

finally作為異常處理的一部分,它只能用在try/catch語句中,並且附帶一個語句塊。

首先finally語句在改程式碼中一定會執行,從執行結果來看,每次return的結果都是4(即finally語句),彷彿其他return語句被遮蔽掉了。 易錯點

在try-catch-finally語句中執行return語句。我們看如下程式碼 在這裡插入圖片描述 事實也確實如此,因為finally用法特殊,所以會撤銷之前的return語句,繼續執行最後的finally塊中的程式碼

3. finalize

finalize()是在java.lang.Object裡定義的,也就是說每一個物件都有這麼個方法。這個方法在gc啟動,該物件被回收的時候被呼叫。其實gc可以回收大部分的物件(凡是new出來的物件,gc都能搞定,一般情況下我們又不會用new以外的方式去建立物件),所以一般是不需要程式設計師去實現finalize的。 特殊情況下,需要程式設計師實現finalize,當物件被回收的時候釋放一些資源,比如:一個socket連結,在物件初始化時建立,整個生命週期內有效,那麼就需要實現finalize,關閉這個連結。   使用finalize還需要注意一個事,呼叫super.finalize();

一個物件的finalize()方法只會被呼叫一次,而且finalize()被呼叫不意味著gc會立即回收該物件,所以有可能呼叫finalize()後,該物件又不需要被回收了,然後到了真正要被回收的時候,因為前面呼叫過一次,所以不會呼叫finalize(),產生問題。 所以,推薦不要使用finalize()方法,它跟解構函式不一樣