前面在講解String時提到了final關鍵字,本文將對final關鍵字進行解析。html
static和final是兩個咱們必須掌握的關鍵字。不一樣於其餘關鍵字,他們都有多種用法,並且在必定環境下使用,能夠提升程序的運行性能,優化程序的結構。下面咱們來了解一下final關鍵字及其用法。app
final從整體上來講是「不可變的」,可用於修改類、方法、變量。性能
final修飾的類,該類不能被繼承。當你確認一個類永遠不會被繼承或不想被繼承,那麼就能夠用final修飾。優化
一樣,對於接口(interface)和抽象類(abstract Class),其本就是爲了「多態」而設計,天然沒法用final關鍵字修飾ui
final類中的成員方法默認也被隱式指定爲final方法。設計
final修飾的方法不可被重寫。3d
例子:code
/** * 父類 * @author LH */ public class FinalDemo1 { public final void test() { } }
final變量包括成員變量和局部變量。變量類型包括基本數據類型、對象。htm
經過final修飾局部基本類型變量(及其包裝類),數值一經初始化(能夠定義時初始化,也能夠在使用前初始化)不可改變。如:對象
final int a = 0; a = 1;//報錯 final int b; b = 1;//編譯經過
經過final修飾局部引用類型變量時,其引用的對象(內存地址)(能夠定義時初始化,也能夠在使用前初始化)不可改變,但對象中存放的數據能夠改變
public static void main(String[] args) { final String str1 = "helloWorld"; str1 = "helloChina";//編譯出錯,String的不可變性,此處返回的是新的對象引用。 final StringBuilder sb = new StringBuilder("hello"); sb.append("world");//編譯經過 sb = new StringBuilder("China");//編譯出錯 }
final修飾的成員變量必須在定義的時候直接初始化,不然會編譯出錯
public class FinalDemo1 { public final int age;//final修飾的基本類型,編譯出錯 public final int age1 = 20;//final修飾的基本類型,編譯經過 public final StringBuilder address;// final修飾的引用類型,編譯出錯 public final StringBuilder address1 = new StringBuilder("中國");//final修飾的引用類型,編譯經過 }
那麼final變量與普通變量之間到底有何區別,看下面的例子
public static void main(String[] args) { String str0 = "helloWorldChina"; String str1 = "helloWorld"; String str3 = str1 + "China"; System.out.println(str0 == str3);//false final String str2 = "helloWorld"; String str4 = str2 + "China"; System.out.println(str0 == str4);//true final String str5; str5 = "helloWorld"; String str6 = str5 + "China"; System.out.println(str0 == str6);//false }
str0 == str3運行結果爲false,這是由於經過「+」生成了一個新的字符串對象,返回的引用地址和str0再也不同樣,這在《Java基礎(三) String深度解析》中有講解。
那麼str0 == str4的執行結果爲何是true?
經過final修飾的變量,若是在編譯期均可以知道確切值(定義變量的時候就初始化),那麼在編譯器會將其當作常量使用,全部用到該變量的地方就至關於直接使用該常量,String str4 = str2 + "China" 在編譯期間都已經合併處理成String str4 = "helloWorldChina",所以str0與str4引用了常量池中同一個字符串字面量的地址,故而結果爲true。
而str0 == str6的執行結果爲false也很好理解
str5在編譯期並不知道確切值,而是在使用以前才進行初始化,所以編譯器沒法事先進行合併處理,str6經過「+」生成了一個新的字符串對象,返回的引用地址和str0也再也不同樣。
而針對基本數據類型來講定義爲final變量與普通變量,比較結果來講並沒有差別
public static void testint(){ int int0 = 8; final int int1; int1 = 4; int int2 = int1 + 4; System.out.println(int2 == int0);//true }
由於基本數據類型並不存在引用傳遞的概念,基本類型變量也是字面常量,因此對基本類型的操做都是直接對值的操做,和引用不同,比較的並不是地址。
本文主要對final關鍵字的原理進行了講解,同時對其基本用法進行了說明,包括final修飾的類,final修飾的方法和final修飾的變量,另外文中String變量經過==比較只是爲了更加清晰的說明final原理,實際應用場景比較的時候仍是用equals()方法,final也常常和static配合使用做爲「全局常量」,如有不對之處,請批評指正,望共同進步,謝謝!