1. 程式人生 > >final/finally/finalize的區別

final/finally/finalize的區別

原文地址:https://www.cnblogs.com/mengyan/archive/2012/08/21/2649473.html
一、性質不同

(1)final為關鍵字;

(2)finalize()為方法;

(3)finally為為區塊標誌,用於try語句中;

二、作用

(1)final為用於標識常量的關鍵字,final標識的關鍵字儲存在常量池中(在這裡final常量的具體用法將在下面進行介紹);

(2)finalize()方法在Object中進行了定義,用於在物件“消失”時,由JVM進行呼叫用於對物件進行垃圾回收,類似於C++中的解構函式;使用者自定義時,用於釋放物件佔用的資源(比如進行I/0操作);

(3)finally{}用於標識程式碼塊,與try{}進行配合,不論try中的程式碼執行完或沒有執行完(這裡指有異常),該程式碼塊之中的程式必定會進行

三、final詳解

1定義變數

1.1 final定義基本型別變數時,要求變數初始化必須在宣告時或者建構函式中,不能用於其它地方。該關鍵字定義的常量,除了初始化階段,不能更改常量的值。

1.2 final定義物件的引用,該引用的初始化與定義常量時的要求一致;該關鍵字定義的物件內容可以改變,但是引用指向的地址不能改變;

2定義引數

如果傳入該引數定義的變數時,方法不能對該引數內容進行修改(錯誤),與定義變數的修改規則相同;java方法中傳遞基本型別時是傳值的,java方法對於物件的傳遞是傳參的;<歸根結底,java中方法的傳遞是依靠傳遞“副本”:對於基本型別,首先建立一個Copy,並將傳入的值賦值給Copy,然後對Copy進行操作;對於物件型別,首先建立一個引用Copy,並將傳入的物件引用賦值給Copy>

比如:method(final int test);

有些書上說,這裡final定義引數,尤其是物件的引數很有作用,不能在方法內對於物件的內容進行改變,這樣的說法是錯誤的!原來我也認為這樣有些函數語言程式設計的特點,不能對於物件的內容進行修改該,這裡依舊可以對物件的內容進行修改。

String天生就是final型別的!

3定義方法

(1)使用final關鍵字定義的方法,不能被子類繼承;

(2)允許編譯器將所有對此方法的呼叫轉化為inline(行內)行為,即可以將此方法直接複製在呼叫處,而不是進行例行的方法呼叫(儲存斷點、壓棧),這樣會使程式的效率升高。但是---------如果過多的話,這樣會造成程式碼膨脹,反而會影響效率,所以該方法要慎用。。

4定義類

一個任何final類無法被任何人繼承,這也就意味著此類在一個繼承樹中是一個葉子類,並且此類被認為是很完美的,不需要進行任何修改(總之是不推薦使用)

final

用於修飾類、成員變數和成員方法。final修飾的類,不能被繼承(String、StrngBuilder、StringBuffer、Math,不可變類),其中所有的方法都不能被重寫,所有不能同時用abstract和final修飾(abstract修飾的是抽象類,抽象類是用於被子類繼承的,和final起相反的作用);final修飾的方法不能被重寫,但是子類可以用父類中final修飾的方法;final修飾的成員變數是不可變的,如果成員變數是基本資料型別,初始化之後成員變數的值不能被改變,如果成員變數是引用型別,那麼它只能指向初始化時指向的那個物件,不能再指向別的物件,但是物件中的內容是允許改變的。

finally

finally是在異常處理時提供finally塊來執行任何清除操作。不管有沒有異常被丟擲、捕獲都會被執行。try塊中的內容是在無異常時執行到結束。catch塊中的內容,是在try塊內容發生catch所宣告的異常時,跳轉到catch塊中執行。finally塊則是無論異常是否發生都會執行finally塊的內容,所以在程式碼邏輯中有需要無論發生什麼都必須執行的程式碼,可以放在finally塊中。

finalize

finalize是方法名,java技術允許使用finalize()方法在垃圾收集器將物件從記憶體中清楚出去之前做必要的清理工作。這個方法是由垃圾收集器在確定這個物件沒有被引用時對這個物件呼叫的,它是在Object類中定義的,因此所有的類都繼承了它。子類覆蓋finalize()方法以整理系統資源或者執行其他清理工作。finalize()方法是在垃圾收集器刪除物件之前對這個物件呼叫的。