final關鍵字可以修飾類虏肾、方法廓啊、變量,具體如下:
1封豪、被final修飾的類不可以被繼承谴轮;
2、被final修飾的方法不可以被重寫吹埠;
3第步、被final修飾的變量不可以被再次賦值;
說到第3點這里稍微多說個case缘琅,比如通過反射機制能否修改final字段呢粘都?這個問題還是要分情況看的,如下:
情況1
class Obj {
private final int a = 1;
private final String b = "hello";
public int getA() { return a;}
public String getB() { return b; }
}
類似這樣的代碼刷袍,final關鍵字作用在基本數(shù)據(jù)類型或者字符串身上翩隧,那么在運行時,通過反射機制是無法修改a或者b
的值的呻纹,原因是對這種情況下的getXXX方法堆生,編譯器做了優(yōu)化,直接替換成了常量內(nèi)容雷酪,即上面的getA()
方法實際變成了如下的代碼:
public int getA() { return 1; }
所以淑仆,你通過反射對字段的修改,無法通過getA()
方法體現(xiàn)出來太闺;
情況2
class Obj {
private final int a; // 注意這里,只是聲明沒有同時賦值(即初始化)
private final String b = "hello";
public Obj() { a = 1; // 直到構造器里才賦值了 }
public int getA() { return a;}
public String getB() { return b; }
}
即a
字段在final定義的時候沒有賦值嘁圈,而是在ctor
里才進行了賦值省骂,那么此種情況下通過反射是可以修改a的值的,原因是此種情況下編譯器不會進行情況1里的優(yōu)化處理最住,所以getA()
方法钞澳,返回的還是對a
字段的引用。
情況3
class Obj {
private final Integer a=1; // 注意這里a是Integer引用類型涨缚,而非原生類型
public int getA() { return a;}
}
即使這里字段a
在定義的時候就已經(jīng)賦值了轧粟,但由于其是引用類型,而非基本數(shù)據(jù)類型,所以運行時通過反射當然是可以修改的兰吟。