final關鍵字
可能使用到final的三種情況:數據、方法和類。
1. final 數據
1.一個永不改變的編譯時變量
2.一個在運行時被初始化的值,而不能被改變
一個既是static 又是final的域只佔一段不能改變的存儲空間。
對於基本類型,final使數值恆定不變;
而對於對象引用,一旦引用被初始化指向一個對象,就無法把它改爲指向另一個對象,然而對象自身卻是可以修改的。
一個既使用final 有使用static final的例子
class SelfControl{
private static int counter;
private int id=counter++;
public String toString(){
return "SelfControl "+id;
}
}
class WithStaticFields{
final SelfControl sc=new SelfControl();
static final SelfControl ssc=new SelfControl();
public String toString(){
return "sc= "+sc+"\n"+"ssc"+ssc;
}
}
public class FinalFields {
public static void main(String[] args){
System.out.println("first object");
System.out.println(new WithStaticFields());
System.out.println("second object");
System.out.println(new WithStaticFields());
}
}
運行結果:
first object
sc= SelfControl 1
ssc= SelfControl 0
second object
sc= SelfControl 2
ssc= SelfControl 0
final :在一個對象類唯一;
static final:在多個對象中都唯一;
空白final
是指被聲明爲final但未給定初始值的域。編譯器一定要保證空白final在使用之前一定被初始化。可以在構造器中或者調用this()進行初始化,否則編譯器報錯。使用空白final,一個類中的final域可以做到根據對象的不同而有所不同,但又保持其恆定不變的特性。
class Poppet {
private int i;
Poppet(int ii) { i = ii; }
}
public class BlankFinal {
private final int i = 0; // Initialized final
private final int j; // Blank final
private final Poppet p; // Blank final reference
// Blank finals MUST be initialized in the constructor:
public BlankFinal() {
j = 1; // Initialize blank final
p = new Poppet(1); // Initialize blank final reference
}
public BlankFinal(int x) {
j = x; // Initialize blank final
p = new Poppet(x); // Initialize blank final reference
}
public static void main(String[] args) {
new BlankFinal();
new BlankFinal(47);
}
}
final 參數
在參數列表中將參數指明爲final,將無法在方法中更改參數引用所指向的對象。
class Gizmo {
public void spin() {}
}
public class FinalArguments {
void with(final Gizmo g) {
//! g = new Gizmo(); // Illegal -- g is final
}
void without(Gizmo g) {
g = new Gizmo(); // OK -- g not final
g.spin();
}
// void f(final int i) { i++; } // Can't change
// You can only read from a final primitive:
int g(final int i) { return i + 1; }
public static void main(String[] args) {
FinalArguments bf = new FinalArguments();
bf.without(null);
bf.with(null);
}
}
2. final 方法
對方法使用final,確保在繼承中,使方法的行爲不會改變,並且不會被覆蓋。
3. final 類
final 類表明該類不能被繼承,final類中的方法都被隱式指定爲final,因此無法覆蓋。