final關鍵字
在java中,final的含義在不同的場景下有細微的差別,但總體上來說,它指的是“這是不可變的”。下面,結合例子簡單記錄下final關鍵字的用法
場景1:當final修飾基本數據類型變量時, 一旦變量的值被初始化後, 則不允許被二次賦值
/**
* 場景1:
* 當final修飾基本數據類型變量時, 一旦變量的值被初始化後, 則不允許被二次賦值
*/
private void case1(){
final int i = 0;
// i = 1; error: Cannot assign a value to final variable "i"
final short s = 0;
// s = 0; error: Cannot assign a value to final variable "s"
final long l = 0L;
// l = 0L; error: Cannot assign a value to final variable "l"
final byte b = 0;
// b = 0; error: Cannot assign a value to final variable "b"
final float f = 0;
// f = 0; error: Cannot assign a value to final variable "f"
final char c = 's';
// c = 's'; error: Cannot assign a value to final variable "c"
final double d = 0d;
// d = 0d; error: Cannot assign a value to final variable "d"
final boolean bol = false;
// bol = true; error: Cannot assign a value to final variable "bol"
}
場景2:當final修飾引用型變量時, 則對變量初始化後不能再指向另外一個對象
/**
* 場景2:
* 當final修飾引用型變量時, 則對變量初始化後不能再指向另外一個對象,但是可以修改對象的成員變量值
*/
private void case2(){
final FinalDemoA finalDemoA = new FinalDemoA();
finalDemoA.value = 1;
FinalDemoA finalDemoB = new FinalDemoA();
// finalDemoA = finalDemoB; Cannot assign a value to final variable "finalDemoA"
// finalDemoA = new FinalDemoA(); Cannot assign a value to final variable "finalDemoA"
finalDemoA.value = 2;
}
場景3:當final修飾方法入參變量時, 該入參變量在方法作用域內不允許再指向另外一個對象, 但是可以修改對象的成員變量值,原理與場景2相同
public static void main(String[] args) {
FinalDemoA finalDemoA = new FinalDemoA();
finalDemoA.value = 1;
case3(finalDemoA);
System.out.println("in main Method finalDemoA.value = " + finalDemoA.value);
}
/**
* 場景3:
* 當final修飾方法入參變量時, 該入參變量在方法作用域內不允許再指向另外一個對象, 但是可以修改對象的成員變量值
* 原理同場景2相同
*/
private static void case3(final FinalDemoA finalDemoA){
FinalDemoA finalDemoA1 = new FinalDemoA();
// finalDemoA = finalDemoA1; Cannot assign a value to final variable "finalDemoA"
// finalDemoA = new FinalDemoA(); Cannot assign a value to final variable "finalDemoA"
finalDemoA.value = 2;
System.out.println("in Case3 Method finalDemoA.value = " + finalDemoA.value);
}
-----------------------------------------------------
in Case3 Method finalDemoA.value = 2
in main Method finalDemoA.value = 2
場景4:被final修飾的變量作爲方法入參時, 由於方法入參沒有被final修飾, 故在方法體內可以將該變量指向另外一個對象, 當方法運行結束後, 該final變量將仍指向原對象而不是新對象
public static void main(String[] args) {
final FinalDemoA finalDemoA = new FinalDemoA();
finalDemoA.value = 1;
System.out.println("in main Method finalDemoA.address = " + finalDemoA);
case4(finalDemoA);
System.out.println("in main Method finalDemoA.address = " + finalDemoA);
System.out.println("in main Method finalDemoA.value = " + finalDemoA.value);
}
/**
* 場景4:
* 被final修飾的變量作爲方法入參時, 由於方法入參沒有被final修飾, 故在方法體內可以將該變量指向另外一個對象,
* 當方法運行結束後, 該final變量將仍指向原對象而不是新對象
*/
private static void case4(FinalDemoA finalDemoA){
finalDemoA = new FinalDemoA();
finalDemoA.value = 2;
System.out.println("in Case4 Method finalDemoA.address = " + finalDemoA);
System.out.println("in Case4 Method finalDemoA.value = " + finalDemoA.value);
}
-------------------------------------------------
in main Method finalDemoA.address = FinalDemoA@244038d0
in Case4 Method finalDemoA.address = FinalDemoA@5680a178
in Case4 Method finalDemoA.value = 2
in main Method finalDemoA.address = FinalDemoA@244038d0
in main Method finalDemoA.value = 1
場景5:用final關鍵字修飾方法,它表示該方法不能被覆蓋。類中所有的private方法都隱式地指定爲是final的
場景6:final修飾的類是無法被繼承的。
上面我們講解了final的幾種用法,然而,對於第五種和第六種用法,我們卻甚少使用。這不是沒有道理的,從final的設計來講,這兩種用法甚至可以說是雞肋,因爲對於開發人員來講,如果我們寫的類被繼承的越多,就說明我們寫的類越有價值,越成功。即使是從設計的角度來講,也沒有必要將一個類設計爲不可繼承的。