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