final在Java中並不常用
然而它卻為我們提供了諸如在C語言中定義常量的功能
不僅如此
final還可以讓你控制你的成員
方法或者是一個類是否可被覆寫或繼承等功能
這些特點使final在Java中擁有了一個不可或缺的地位
也是學習Java時必須要知道和掌握的關鍵字之一
final成員
當你在類中定義變量時
在其前面加上final關鍵字
那便是說
這個變量一旦被初始化便不可改變
這裡不可改變的意思對基本類型來說是其值不可變
而對於對象變量來說其引用不可再變
其初始化可以在兩個地方
一是其定義處
也就是說在final變量定義時直接給其賦值
二是在構造函數中
這兩個地方只能選其一
要麼在定義時給值
要麼在構造函數中給值
不能同時既在定義時給了值
又在構造函數中給另外的值
下面這段代碼演示了這一點
import java
util
List;
import java
util
ArrayList;
import java
util
LinkedList;
public class Bat{
final PI=
; //在定義時便給址值
final int i; //因為要在構造函數中進行初始化
所以此處便不可再給值
final List list; //此變量也與上面的一樣
Bat(){
i=
;
list=new LinkedList();
}
Bat(int ii
List l){
i=ii;
list=l;
}
public static void main(String[] args){
Bat b=new Bat();
b
list
add(new Bat());
//b
i=
;
//b
list=new ArrayList();
System
out
println(
I=
+b
i+
List Type:
+b
list
getClass());
b=new Bat(
new ArrayList());
b
list
add(new Bat());
System
out
println(
I=
+b
i+
List Type:
+b
list
getClass());
}
}
此程序很簡單的演示了final的常規用法
在這裡使用在構造函數中進行初始化的方法
這使你有了一點靈活性
如Bat的兩個重載構造函數所示
第一個缺省構造函數會為你提供默認的值
重載的那個構造函數會根據你所提供的值或類型為final變量初始化
然而有時你並不需要這種靈活性
你只需要在定義時便給定其值並永不變化
這時就不要再用這種方法
在main方法中有兩行語句注釋掉了
如果你去掉注釋
程序便無法通過編譯
這便是說
不論是i的值或是 list的類型
一旦初始化
確實無法再更改
然而b可以通過重新初始化來指定i的值或list的類型
輸出結果中顯示了這一點
I=
List Type:class java
util
LinkedList
I=
List Type:class java
util
ArrayList
還有一種用法是定義方法中的參數為final
對於基本類型的變量
這樣做並沒有什麼實際意義
因為基本類型的變量在調用方法時是傳值的
也就是說你可以在方法中更改這個參數變量而不會影響到調用語句
然而對於對象變量
卻顯得很實用
因為對象變量在傳遞時是傳遞其引用
這樣你在方法中對對象變量的修改也會影響到調用語句中的對象變量
當你在方法中不需要改變作為參數的對象變量時
明確使用final進行聲明
會防止你無意的修改而影響到調用方法
另外方法中的內部類在用到方法中的參變量時
此參變也必須聲明為final才可使用
如下代碼所示
public class INClass{
void innerClass(final String str){
class IClass{
IClass(){
System
out
println(str);
}
}
IClass ic=new IClass();
}
public static void main(String[] args){
INClass inc=new INClass();
inc
innerClass(
Hello
);
}
}
final方法
將方法聲明為final
那就說明你已經知道這個方法提供的功能已經滿足你要求
不需要進行擴展
並且也不允許任何從此類繼承的類來覆寫這個方法
但是繼承仍然可以繼承這個方法
也就是說可以直接使用
另外有一種被稱為inline的機制
它會使你在調用final方法時
直接將方法主體插入到調用處
而不是進行例行的方法調用
例如保存斷點
壓棧等
這樣可能會使你的程序效率有所提高
然而當你的方法主體非常龐大時
或你在多處調用此方法
那麼你的調用主體代碼便會迅速膨脹
可能反而會影響效率
所以你要慎用final進行方法定義
final類
當你將final用於類身上時
你就需要仔細考慮
因為一個final類是無法被任何人繼承的
那也就意味著此類在一個繼承樹中是一個葉子類
並且此類的設計已被認為很完美而不需要進行修改或擴展
對於final類中的成員
你可以定義其為final
也可以不是final
而對於方法
由於所屬類為final的關系
自然也就成了 final型的
你也可以明確的給final類中的方法加上一個final
但這顯然沒有意義
下面的程序演示了final方法和final類的用法
final class final{
final String str=
final Data
;
public String str
=
non final data
;
final public void print(){
System
out
println(
final method
);
}
public void what(){
System
out
println(str+
\n
+str
);
}
}
public class FinalDemo { //extends final 無法繼承
public static void main(String[] args){
final f=new final();
f
what();
f
print();
}
}
從程序中可以看出
final類與普通類的使用幾乎沒有差別
只是它失去了被繼承的特性
final方法與非final方法的區別也很難從程序行看出
只是記住慎用
final在設計模式中的應用
在設計模式中有一種模式叫做不變模式
在Java中通過final關鍵字可以很容易的實現這個模式
在講解final成員時用到的程序Bat
java就是一個不變模式的例子
如果你對此感興趣
可以參考閻宏博士編寫的《Java與模式》一書中的講解
到此為止
this
static
super和final的使用已經說完了
如果你對這四個關鍵字已經能夠大致說出它們的區別與用法
那便說明你基本已經掌握
然而
世界上的任何東西都不是完美無缺的
Java提供這四個關鍵字
給程序員的編程帶來了很大的便利
但並不是說要讓你到處使用
一旦達到濫用的程序
便適得其反
所以在使用時請一定要認真考慮
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26924.html