在前兩篇文章中,我們探討了 final 修飾基本類型、引用類型以及方法的行為。本文將透過一個完整的測試程式 FinalDemo.java,實際驗證 final 在不同場景下的表現,並做最終總結。
package zy.pro.jbd.demo;
/**
* 此示例用於測試 final 保留字的用法
*/
import zy.pro.jbd.testbase.A;
public class FinalDemo {
final int numInt1 = 16;
final String str = "zy";
final String str1; // 空白 final 欄位,必須在建構子中初始化
final A a = new A();
public FinalDemo() {
str1 = "zy"; // 初始化空白 final 欄位
}
public static void main(String[] args) {
System.out.println("-------------------------------------------------");
FinalDemo fd = new FinalDemo();
fd.executeFinalTest();
}
public void executeFinalTest() {
this.testFinalInt();
this.testFinalString();
this.testFinalObject();
}
private void testFinalInt() {
// numInt1 += 1; // 編譯錯誤:無法對 final 變數賦值
System.out.println(numInt1);
}
private void testFinalString() {
// str = str + "aaaaa"; // 編譯錯誤:無法對 final 變數賦值
System.out.println(str);
}
public void testFinalObject() {
a.setT(29); // 允許:修改物件內部狀態
System.out.println("t: " + a.getT());
/*
* 以下代碼會導致編譯錯誤:
* A b = new A();
* a = b; // 無法改變 final 參考指向的物件
*/
}
}
numInt1 和 str 宣告時即賦值,任何嘗試重新賦值的操作(如 numInt1++ 或 str = str + "...")都會導致編譯錯誤。這證實了 final 修飾基本類型與 String 時,其值不可變。
str1 在宣告時未初始化,稱為「空白 final」。Java 強制要求在建構子(或實例初始化塊)中對其賦值,否則編譯失敗。這保證了 final 欄位在物件建立完成前處於確定狀態。
final A a = new A(); 表示參考 a 不能指向另一個 A 實例,但可以透過 a.setT(29) 修改該物件內部的可變狀態。註釋掉的代碼 a = b; 將導致編譯錯誤,印證了「引用不可變,物件內容可變」的原則。
final 使值不可改變。final 鎖定參考指向的物件,但物件內部狀態仍可修改。final 方法不可被覆寫,但可被繼承;private 方法對子類不可見,子類可定義同名方法而不構成覆寫。本文來自編程入門網:原文連結