Java基礎(五) final關鍵字淺析

前面在講解String時提到了final關鍵字,本文將對final關鍵字進行解析。html

staticfinal是兩個咱們必須掌握的關鍵字。不一樣於其餘關鍵字,他們都有多種用法,並且在必定環境下使用,能夠提升程序的運行性能,優化程序的結構。下面咱們來了解一下final關鍵字及其用法。app

final從整體上來講是「不可變的」,可用於修改類、方法、變量。性能

一. final類

final修飾的類,該類不能被繼承。當你確認一個類永遠不會被繼承或不想被繼承,那麼就能夠用final修飾。優化

一樣,對於接口(interface)和抽象類(abstract Class),其本就是爲了「多態」而設計,天然沒法用final關鍵字修飾ui

final類中的成員方法默認也被隱式指定爲final方法。設計

二. final方法

final修飾的方法不可被重寫。3d

例子:code

/**
 * 父類
 * @author LH
 */
public class FinalDemo1 {
    public final void test() {
        
    }
}

三. final變量

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配合使用做爲「全局常量」,如有不對之處,請批評指正,望共同進步,謝謝!

相關文章
相關標籤/搜索