在C#經典面試中摻雜過Java的final關鍵字,主要用於類不能被繼承,在C#則是利用關鍵字seal修飾類爲密封類,而在Java中的final關鍵字的具體用法包含C#中const、readonly、seal三者使用之和,本節咱們來聊聊Java的關鍵字final。面試
經過final關鍵字修飾意爲沒法改變,在Java早期版本經過final能夠改善性能或者提升效率,但現現在版本final已經無所謂性能,咱們只關注於在設計時應用final的具體場景,final關鍵字包含兩層含義:其一,編譯時常量不變,其二,運行時初始化值然後不被改變。這二者其實就是C#中的const和readonly關鍵字的使用。 final主要用於三種狀況,修飾數據、方法、類,但本質上都是表示不可變,至於「不可變」的含義就看對應哪一種場景。固然加上static修飾符只是代表在內存中只保存一份數據,這裏咱們就不作過多探討。編程
編譯時常量和C#中概念一致,只不過C#用const修飾,同時對於變量的命名都是採用大寫方式,單詞與單詞之間用下劃線隔開,好比以下編譯時常量安全
public final int VALUE_ONE = 1;
上述已經說過,final不單單只是對於編譯時必須爲常量,還能夠用於運行時初始化時的值,好比經過隨機函數生成值dom
public static Random random = new Random(); public final int VALUE_ONE = random.nextInt(20);
這種運行時初始化值方式就是C#中的readonly,以下:函數
public static Random random = new Random(); public readonly int VALUE_ONE = random.Next(20);
對於C#中的readonly初始值,咱們知道除了在定義時賦值,也能夠在構造函數中初始化值,如果再加上static,很顯然必須在靜態構造函數中初始化性能
class Program { public readonly int VALUE_ONE; public Program() { VALUE_ONE = 1; } }
final關鍵字一樣也能達到上述使用readonly的效果,只不過在Java中稱其爲「空白final」,所謂空白final是指被聲明爲final但未給定初始值,可是不管何種狀況,編譯器必須確保在使用數據以前必須進行初始化學習
public class Main { public final int VALUE_ONE; public Main() { VALUE_ONE = 1; } }
不管是做爲方法參數仍是做爲初始化變量的修飾,咱們能夠更改該參數裏面的值,可是沒法更改參數引用所指向的對象。以下示例爲修飾初始化類變量,做爲方法參數同理,這裏再也不闡述。this
class Value { int i; public Value(int i) { this.i = i; } } public class FinalDemo { public final Value value = new Value(1); }
public class Main { public static void main(String[] args) { FinalDemo finalDemo = new FinalDemo(); //能夠更改final參數裏的值 finalDemo.value.i = 2; //不能更改參數所指向的對象(編譯報錯) finalDemo.value = new Value(2); } }
final修飾方法是將方法進行鎖定,以防止任何繼承類修改它自己的含義,此意爲用以標記該方法不能被覆蓋(對於對象範圍內)或隱藏,這爲後續開發人員建立其方法所在類的子類沒法覆蓋其行爲提供有力的保證。好比以下計數器則是一個很好的例子spa
public class Counter { private int counter = 0; public final int count() { return ++counter; } public final int reset() { return (counter = 0); } }
可是咱們去掉上述count方法的修飾符,進行以下操做,很顯然將破壞原始方法的行爲,打印出結果爲2設計
Counter c = new Counter() { public int count() { super.count(); return super.count(); } }; System.out.println(c.count());
若將整個類定義爲final時,這說明此類將不會被繼承和C#中seal修飾符一模一樣,或出於安全考慮,或出於設計已肯定該類不會再作任何變更,不但願該類有子類
public final class Counter { } //編譯發生錯誤 class SubCounter extends Counter { }
本節咱們詳細講解了final關鍵字,該關鍵字是C#中const、readonly、seal三者使用的組合,Java編程思想雖然將其劃分爲數據、方法、類,這裏我認爲劃分爲變量(包含數據和參數)、方法、類更合理。其實語法都大同小異,仍是那句話,學習的本質在於概括總結並觸類旁通從而內化。