小而有料的final

閱讀原文:小而有料的final(想聽文章核心內容語音對話版,請到微信公衆號——碼上實戰,閱讀原文)java

final這塊肉雖然小,但不可不知,由於不只面試可能會問,實際中也常使用。 就問你常量聲明時你爲何要加final?它有哪些做用?你思考過嗎?面試

final一般指被修飾的東西不能被改變的,不能被改變的緣由旺每每出於設計和效率的考慮。編程

先看final能修飾什麼?安全

  • 修飾變量
  • 修飾方法
  • 修飾類
  • 修飾參數

不一樣的修飾有什麼不一樣的做用呢?下面慢慢道來:微信

final常量

final修飾的常量必須在被使用前進行初始化,初始化的方式無非兩種:定義時賦值或構造函數內賦值網絡

final修飾常量基本類型和引用類型有些不一樣,我分開講。dom

基本數據類型

public class Test {

    private final int A;
    private final int B = 3;
    private final int C = new Random().nextInt();

    public Test() {
        this.A = 5;
    }
    public Test(int a) {
        this.A = a;
    }
}

複製代碼
  • 爲何常量B要用final修飾?函數

    由於這種肯定值(定義便當即賦值)的final常量,編譯器會在編譯時將該常量值帶入到任何可能用到它的計算式中,這會減輕運行時的一些負擔。 好比 int d = 3 * B; 那麼編譯後至關於 int d = 9;this

  • final修飾的常量值是在編譯期間被肯定的嗎?spa

    注意上面的變量C,咱們並不能覺得final修飾的就能在編譯時知道它的值,C的值只有在運行時被初始化時纔會顯現。

引用類型

引用類型不能改變指的是引用被初始化指向一個對象後,就再也沒法改成指向其餘對象,但其指向的對象自己是能夠被修改的

public class B {

    //final常量d指向了對象D
    private final D d =new D();

    //這個方法改變了對象D的內容
    public D change(){
        this.d.setS("change");
        return d;
    }

    //注意這個方法,將常量d的引用改變了
    public D refnewD(){
        this.d = new D();
        return d;
    }
    
    class D {
        private String s= "init";

        public String getS() {
            return s;
        }

        public void setS(String s) {
            this.s = s;
        }
    }
}
複製代碼

上面代碼是沒法編譯的,由於this.d=new D()會提示Cannot assign a value to final variable 'd',可是你卻能夠調用change()方法來改變d對象的s變量值。

final方法

  • 爲何使用final修飾方法
  1. 設計:把方法鎖定,防止繼承類修改它的含義。
  2. 效率:早期編譯器會將final方法全部的調用轉爲內嵌調用,隨着JVM的提升,這種方式已被丟棄。
  • final和private

當一個方法被private修飾,這會隱式的指定爲final,這也會使得子類沒法覆蓋此方法,能夠對private方法增長final修飾,但對該方法並不能增長任何意義。

final類

String類是final應用的典型例子,可去查看面試別再問我String了

  • 爲何要把類指定爲final?

出於安全考慮或其餘緣由,你不但願該類有任何變更或被繼承。

一旦類被final修飾,即表明final類中的全部成員變量和方法都會隱式的final.

final參數

在方法的參數列表中將參數指定爲final,即表明該參數引用所指向的對象是沒法改變的; 若爲基本類型,則表示值能夠讀取,但沒法修改。修飾狀況和final常量相似。也可結合這題不會!別說你懂值傳遞與引用傳遞看。

final相關

static 和 final

  1. static強調的是該數據只存在一份,且是屬於類的,不是屬於對象。
  2. final強調該數據不可變,且是屬於對象的。
public class C {

    private final double A = 3.14D;

    private static double b = 3.14D;

    public static void main(String[] args) {
        new C();
        new C();
        new C();
    }
}
複製代碼

上面代碼運行後,A會存在3個,但b只有一個。

final,finally和finalize

  • finally

    是在異常處理時配合try-catch執行清理操做,須要清理的資源包括:打開的文件或網絡鏈接等,它會把內存以外的資源恢復到他們的初始狀態。不管try中是否有異常出現,finally裏的操做都會被執行。

  • finalize

    這是Object基類的一個方法,垃圾收集器在將對象清除出內存以前調用的清理資源方法,且此方法只會被系統調用一次,其實finalize能作的工做,try-finally能作的更好,《深刻理解Java虛擬機》中建議你們忘掉這個方法的存在。

參考書籍

  • Java編程思想
  • 深刻理解Java虛擬機

更多精彩技術文章盡在微信公衆號:碼上實戰

相關文章
相關標籤/搜索