最後

Java 中的 final 可以引用變數,方法和類。有三個簡單的規則:

  • 最終變數無法重新分配
  • 最終方法無法覆蓋
  • 最後一堂課不能延期

用法

良好的程式設計實踐

一些開發人員認為在可能的情況下標記變數 final 是一種很好的做法。如果你有一個不應更改的變數,則應將其標記為 final。

final 關鍵字 if 的重要用途是方法引數。如果要強調方法不更改其輸入引數,請將屬性標記為 final。

public int sumup(final List<Integer> ints);

這強調了 sumup 方法不會改變 ints

內部類訪問

如果你的匿名內部類想要訪問變數,則該變數應標記為 final

  public IPrintName printName(){
    String name;
    return new IPrintName(){
        @Override
        public void printName(){
            System.out.println(name);
        }
    };
}

這個類不編譯,因為變數 name 不是 final。

Version >= Java SE 8

有效的最終變數是一個例外。這些區域性變數只寫入一次,因此可以作為最終變數。有效的最終變數也可以從匿名類中訪問。

final static 變數

即使 final 變數 foo 不是 static,下面的程式碼完全合法,但是如果是 static 則不會編譯:

class TestFinal {
    private final static List foo;

    public Test() {
        foo = new ArrayList();
    }
}

原因是,讓我們再說一遍,最後的變數不能重新分配。由於 foo 是靜態的,因此它在 TestFinal 的所有例項之間共享。當建立類 TestFinal 的新例項時,將呼叫其建構函式,因此將重新分配 foo,而編譯器不允許這樣做。在這種情況下初始化變數 foo 的正確方法是:

class TestFinal {
    private static final List foo = new ArrayList();
    //..
}

或者使用靜態初始化程式:

class TestFinal {
    private static final List foo;
    static {
        foo = new ArrayList();
    }
    //..
}

當基類實現派生類不應該更改它的一些重要功能時,final 方法很有用。它們也比非最終方法更快,因為沒有涉及虛擬表的概念。

Java 中的所有包裝類都是最終的,例如 IntegerLong 等。這些類的建立者不希望任何人都可以將 Integer 擴充套件到他自己的類中並改變 Integer 類的基本行為。使類不可變的要求之一是子類不能覆蓋方法。最簡單的方法是將類宣告為 final