final在java中是一個很常用的關(guān)鍵字棕兼。它通常被用來修飾類宴猾、方法和變量(包括常量和變量)圆存。
1、final修飾類
final仇哆,顧名思義是最終的意思沦辙。當用final來修飾一個類的時候,表示這個類不能被繼承讹剔。而在這個final修飾的類中怕轿,它的成員變量是可以根據(jù)自己的需要來設(shè)置為final(也就是說,final類中的成員變量不一定都是被final修飾)辟拷。但是注意一點撞羽,在被final修飾的類中,它的成員方法是會被隱式的指定為final方法衫冻。
String類就是一個常見的被final修飾的類诀紊。
final class Box {
Box(){}
String boxName = "box";
}
//當我們寫出一段這樣的代碼時,編譯器會自動提示錯誤隅俘。
//Cannot inherit from final `Box`(不能繼承final Box類)邻奠,即直接告訴了我們final修飾的類不能被繼承
/*
class Fox extends Box {
}
*/
2、final修飾方法
"使用final方法的原因有兩個为居。第一個原因是把方法鎖定碌宴,以防任何繼承類修改它的含義;第二個原因是效率蒙畴。在早期的Java實現(xiàn)版本中贰镣,會將final方法轉(zhuǎn)為內(nèi)嵌調(diào)用呜象。但是如果方法過于龐大,可能看不到內(nèi)嵌調(diào)用帶來的任何性能提升碑隆。在最近的Java版本中恭陡,不需要使用final方法進行這些優(yōu)化了。"
即父類中的final方法是不能被子類覆蓋(重寫)的
還有一點值得注意:如果父類中被final修飾的方法同時設(shè)置了訪問權(quán)限private上煤,則這個方法直接不會被子類繼承到休玩。此時,可以在子類中定義一個相同方法名和參數(shù)的方法劫狠,此時不再產(chǎn)生重寫與final的矛盾拴疤,而是在子類中重新定義了新的方法(與父類中的完全沒有關(guān)系)。
(類的private方法會隱式地被指定為final方法)
public class B extends A {
public static void main(String[] args) {
}
public void getName() {
}
}
class A {
/**
* 因為private修飾独泞,子類中不能繼承到此方法呐矾,因此阐肤,子類中的getName方法是重新定義的孕惜、
* 屬于子類本身的方法衫画,編譯正常
*/
private final void getName() {
}
/* 因為pblic修飾削罩,子類可以繼承到此方法进陡,導(dǎo)致重寫了父類的final方法趾疚,編譯出錯
public final void getName() {
}
*/
}
3糙麦、final修飾變量
final成員變量表示常量丛肮,只能被賦值一次焚廊,賦值后值不再改變节值。
public static final int data = 1;
public static final Fox fox = new Fox();
當final修飾一個基本數(shù)據(jù)類型時,表示該基本數(shù)據(jù)類型的值一旦在初始化后便不能發(fā)生變化匿乃;如果final修飾一個引用類型時,則在對其初始化之后便不能再讓其指向其他對象了宛徊,但該引用所指向的對象的內(nèi)容是可以發(fā)生變化的。本質(zhì)上是一回事苞氮,因為引用的值是一個地址笼吟,final要求值贷帮,即地址的值不發(fā)生變化撵枢。
final修飾一個成員變量(屬性)诲侮,必須要顯示初始化箱蟆。這里有兩種初始化方式空猜,一種是在變量聲明的時候初始化;第二種方法是在聲明變量的時候不賦初值搜贤,但是要在這個變量所在的類的所有的構(gòu)造函數(shù)中對這個變量賦初值。
public void changeValue(final int i){
//final參數(shù)不可改變
//i++;
System.out.println(i);
}
當函數(shù)的參數(shù)類型聲明為final時,說明該參數(shù)是只讀型的饺蔑。即你可以讀取使用該參數(shù),但是無法改變該參數(shù)的值发皿。