首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 核心基礎知識深度解析:六大必懂觀念,初學者與進階者的分水嶺

     編輯:Java 相關知識

前言

這六個問題看似基礎,實則直擊 Java 物件模型、記憶體語意與語言設計哲學的核心。若你自以為「超越初學者」卻答不上來,請誠實地回歸基礎,重新建立正確心智模型。

問題一:String s = "Hello world!"; 到底宣告了什麼?

錯誤回答:「宣告了一個內容為 Hello world! 的 String 物件。」

正確回答:宣告了一個名為 s、型別為 String 的參考變數,目前指向字串常量池中的 "Hello world!" 物件。

String s = "Hello world!";  // 參考變數 s → 字串常量池物件
String s2 = s;              // 新參考變數 s2 → 同一個物件,並未建立新物件

關鍵區別:變數 ≠ 物件。Java 無變數直接存物件,只有參考指向物件。

問題二:== vs equals() —— 比的是「地址」還是「內容」?

String a = new String("foo");
String b = new String("foo");
System.out.println(a == b);        // false:比較參考地址(兩個 new = 兩個堆上物件)
System.out.println(a.equals(b));   // true:String 覆寫 equals 比較字元內容
  • ==:永遠比較參考值(記憶體地址),基本型別比值、參考型別比地址。
  • equals():Object 預設同 ==,語意由類別設計者決定。String、Integer、集合類別皆覆寫為內容比較。
⚠️ 使用 HashSet/HashMap/HashTable 時,必須確認該類別正確覆寫 equals() 與 hashCode(),否則會出現「明明相等卻存兩份」或「找不到已存入物件」的詭異行為。

問題三:String 到底變了沒有?—— 不可變模式

String s = "Hello";
s = s + " world!";

發生了什麼:

  1. s 原指向常量池 "Hello"
  2. s + " world!" 產生新物件 "Hello world!"(在堆上或常量池,視 JDK 版本優化)
  3. s 參考指向新物件,舊 "Hello" 仍在記憶體(若無其他參考則待 GC)

結論:String 物件一旦建立內容永不變,所有「修改」操作實則產生新物件。

效能啟示

  • 大量字串拼接 → 用 StringBuilder(非執行緒安全、效能佳)或 StringBuffer(執行緒安全)。
  • 常量字串初始化 → s = "value"; 而非 new String("value"),後者每次強制新建物件,浪費記憶體與 CPU。

問題四:final 到底鎖住了什麼?

final StringBuffer a = new StringBuffer("immutable");
a = new StringBuffer("another");  // ❌ 編譯錯誤:參考不可變

final StringBuffer b = new StringBuffer("immutable");
b.append(" broken!");             // ✅ 編譯通過:物件內容可變

鐵律:final 只鎖住參考變數的指向,不鎖住被指向物件的內部狀態。

💡 多執行緒環境下,final 參考指向的可變物件若被多執行緒共享修改,仍會有競態條件。不可變物件才是真正的執行緒安全。

問題五:變數初始化規則—— 哪些自動、哪些強制?

變數類型自動初始化預設值備註
類別屬性✅ 是0/0.0/false/null/\\u0000static 隨類別載入、instance 隨建構子
區域變數❌ 否無使用前必須明確賦值,否則編譯錯誤
方法參數✅ 是呼叫端傳入值本質是區域變數,但進入方法時已初始化

區域變數初始化陷阱

int x;
if (cond) x = 1;  // ❌ 編譯錯誤:cond 為 false 時 x 未初始化
// 必須寫成:
int x = 0;        // 或在 else 也賦值

問題六:instanceof —— 型別檢查的正確姿勢

String s = "test";
boolean b = s instanceof Object;  // true:String 繼承 Object

反模式:用 instanceof 分派行為(違反開放封閉原則、模擬多型)。

// ❌ 惡例
if (bill instanceof PhoneBill) calcPhone(bill);
else if (bill instanceof GasBill) calcGas(bill);

正統做法:方法多載或多型。

// ✅ 多載
double calculate(PhoneBill b) { ... }
double calculate(GasBill b) { ... }

// ✅ 多型(Bill 定義抽象 calculate(),子類別實作)
bill.calculate();

總結:建立正確心智模型的六大關鍵

  1. 參考 ≠ 物件:變數存地址,物件在堆上。
  2. == 比地址,equals 比語意:查文件確認 equals 契約。
  3. String 不可變:拼接用 Builder,常量用字面值。
  4. final 鎖參考,不鎖物件:執行緒安全靠不可變或同步。
  5. 屬性自動初始,區域強制初始:宣告時就給預設值。
  6. instanceof 是最後手段:優先用多型/多載/訪問者模式。

掌握這六點,你就真正跨越了「會寫語法」到「懂 Java 運行本質」的鴻溝。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved