首頁  >  文章  >  Java  >  深入Java Final

深入Java Final

巴扎黑
巴扎黑原創
2017-05-21 14:10:461172瀏覽

這篇文章,小編將為大家介紹Java Final,有需要的朋友可以參考一下

JAVA關鍵字final用於修飾資料、方法或類,通常意味著“無法改變的” ,既資料不能改變,方法不能覆蓋,類別不能繼承。一般採用final有兩種原因:設計和效率。而隨著JAVA版本的更新,一些效率上的問題可以交由編譯器和JVM處理。因此,採用final來解決效率問題就顯得不是那麼重要了。

Final修飾符大多運用於基本資料型別(primitive)域或不可變(immutable)類別的域(如果類別中的所有方法方法都不會改變其對象,這種類別就是不可變類別。 String就是一個不可變類別)。

【final資料】

Final關鍵字用修飾資料主要有兩種情況:

1. 編譯期常數

2. 運行時初始化的值

對於編譯期常數,指的是一個既是final又是static的域(依照慣例,編譯期常數全部用大寫字母命名,並且用下劃線分隔各個單字),它只佔據一段不能改變的儲存空間。編譯器可以將編譯期常數代入到任何可能用到它的運算式中,也就是說,可以在編譯時執行運算式,這相對減輕了執行時間負擔。編譯期常數在定義時必須對它賦值(不一定是基本型別)。

運行時初始化的值,對於基本類型,final使得其值不可改變;而對於物件引用,final使得引用不可改變,即無法將其改為指向另一個對象,然而,對象本身卻可以修改(適用於數組,數組也是物件)。

程式碼如下:

public class javaFinalData{
    private static final String TESTD = "test";
    public static final String TESTE = "test";
    public static final String[] TESTF = {"1","2"}; //非基本类型
    private static final String[] TESTG = new String[2];
    public static void main(String args[]){
        final int testA = 1;
        final String testB = "test";
        final int[] testC = {1,1,2,};
        System.out.println(testC[1]);
        testC[1] = 123;
        System.out.println(testC[1]);
    }
}

【未賦值的final域】

JAVA允許產生未賦值的final域,但是必須在域的定義處或每個構造器中對final域進行賦值(有多少個構造器就必須賦值幾次),確保在使用前被初始化。採用這種方式,可以使得final運用得更靈活,在同一個類別中,根據不同的物件賦予不同的值,卻又保持不可改變的特性。

程式碼如下:

public class javaBlankFinal{
    private final int blank;
    public javaBlankFinal(){
        blank = 2011;
    }
    public javaBlankFinal(int temp){
        blank = 2012;
    }
    public javaBlankFinal(String temp){
        blank = 2014;
    }
    public static void main(String args[]){
        new javaBlankFinal();
    }
}

【final方法】

       使用final方法有兩方面原因:一是將方法鎖定,防止方法被覆蓋,確保在繼承中方法行為保持不變;二是將方法呼叫轉為內聯呼叫(inlining),以減少方法呼叫的開銷。但是,在最近的版本中,JVM可以自行進行最佳化,因此無需使用final方法來處理效率問題。

       關於final方法,還有一點要注意,所有類別中的private方法都隱含地指定為final方法(也可以為其加上final修飾,但沒有意義)。當你試圖覆寫一個private方法,編譯器並沒有報錯,但是,實際上你並沒有覆寫該方法,只是產生了一個新方法。因為private方法是無法被外部類別所存取的,當然就無法覆蓋到它了。

       使用@Override註解可以預防上述問題。如程式所示:

程式碼如下:

class finalFunction{
    private void finalFunctionA(){
        System.out.println("finalFunctionA");
    }

    private final void finalFunctionB(){
        System.out.println("finalFunctionB");
    }

    final void finalFunctionC(){
        System.out.println("finalFunctionC");
    }

    void functionD(){}
}
class overrideFinalFunction extends finalFunction{
    //@Override   添加@Override注解可以识别是否是override
    public void finalFunctionA(){               
        System.out.println("override finalFunctionA");
    }

    public final void finalFunctionB(){
        System.out.println("override finalFunctionB");
    }

    //final void finalFunctionC(){}   //Cannot override the final method from finalFunction

    @Override   
    void functionD(){} //真正的override方法
}
public class javaFinalFunction extends finalFunction{
    public static void main(String args[]){
        finalFunction ff = new finalFunction();
        //ff.finalFunctionA();  //无法调用private方法
        //ff.finalFunctionB();

        overrideFinalFunction off = new overrideFinalFunction();
        off.finalFunctionA();   //public方法
        off.finalFunctionB();
    }
}

【final類別】

使用final類別一般是出於設計原因,不允許該類別被繼承。這樣可以確保類的行為不會改變,或許還能避免一些安全危機。 Final類別中所有的方法都隱式指定為final方法,因此無法被覆寫(因為final類別禁止繼承,也就無法覆寫其類別中的方法)。在Java核心API中,有許多應用final的例子,例如java.lang.String。為String類別指定final防止覆寫length()等方法。

對於final域來說,即使將一個類別宣告為final,類別中的域不會自動成為final域。

程式碼如下:

final class finalClass{
    int testA = 2011;
}
//class extendFinalClassextends finalClass{}  //can not extendthe final class finalClass
public class javaFinalClass{
    public static void main(String args[]){
       finalClass fc = new finalClass();
       System.out.println(fc.testA);
       fc.testA = 2012;
       System.out.println(fc.testA);
    }
}

以上是深入Java Final的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn