本文為「Java 基礎面試題」系列第一部分,涵蓋面向物件四大特徵、存取修飾符、基本型別與包裝類、運算子、記憶體模型、String 不變性、位運算技巧、流程控制、建構子/重載/重寫、equals/hashCode 契約、final 關鍵字、抽象類與介面、內部類、記憶體洩漏、GC 機制、序列化、類載入器雙親委派、字元編碼、匿名內部類。適合初中級開發者建立扎實知識體系。
Overload(編譯期/靜態綁定)vs Override(運行期/動態綁定)。| 修飾符 | 同類 | 同包 | 子類(異包) | 非子類(異包) |
|---|---|---|---|---|
| private | ✓ | ✗ | ✗ | ✗ | default | ✓ | ✓ | ✗ | ✗ |
| protected | ✓ | ✓ | ✓ | ✗ |
| public | ✓ | ✓ | ✓ | ✓ |
注意:外部類只能 public 或 default;成員(含內部類)可用四種。
byte, short, int, long, float, double, char, booleanByte, Short, Integer, Long, Float, Double, Character, Booleanfloat f = 3.4; ❌(3.4 是 double)→ float f = 3.4F; 或 (float)3.4short s = 1; s = s + 1; ❌(int 運算)→ s += 1; ✅(隱含強轉)
Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;
System.out.println(f1 == f2); // true
System.out.println(f3 == f4); // false
解析:Integer.valueOf() 快取 -128 ~ 127 範圍物件。範圍內復用快取(== 為 true),範圍外新建物件(== 為 false)。比較包裝類數值請用 .equals()。
goto、const 為保留字,不可使用int vs Integer:基本型別 vs 物件。Java 5+ 自動拆裝箱橋接兩者&:邏輯與(雙邊必算)或位運算&&:短路與,左邊 false 右邊不執行if (str != null && !str.isEmpty()) 順序不可換,& 會拋 NPE| 區域 | 存放內容 | 特點 |
|---|---|---|
| Stack (棧) | 基本型別變數、物件引用、方法幀 | 速度最快、容量小、執行緒私有 |
| Heap (堆) | new 出來的物件、陣列 | GC 管理、全域共享、可擴展至虛擬記憶體 |
| Static Area (靜態區) | 字面量(100、"hello")、常量、static 變數 | 類載入時分配、類卸載時釋放 |
String s = new String("hello");
// s 在 Stack
// new String() 物件在 Heap
// "hello" 字面量在 Static Area
補充:Java 6+ 逃逸分析 可將未逃逸物件分配在 Stack(標量替換),提升效能。
Math.round(11.5) → 12Math.round(-11.5) → -11floor(x + 0.5))byte, short, char, intenumStringlong2 * 8 → 2 << 3(左移 3 位 = 乘 2³)num * 31 → (num << 5) - num(HashCode 常用優化,現代 JVM 自動優化)arr.length(屬性)str.length()(方法).length 屬性
outer: for (int i=0; i<10; i++) {
for (int j=0; j<10; j++) {
if (condition) break outer; // 標籤 break
}
}
建議:慎用標籤 break/continue,易降低可讀性,優先重構為方法返回。
Overload:同類、同名、參數列表不同(型別/個數/順序),與返回型別無關Override:子類覆寫父類,返回型別兼容、拋出異常子集、存取權限不嚴格於父類String 為 final 類,**不可繼承**。復用請用組合/委派x.equals(y) == true → x.hashCode() == y.hashCode() 必須成立hashCode() 相等 → equals() 不一定相等(哈希碰撞)HashSet 可存入「相等」重複物件、HashMap 效能退化為 O(n)高質量 equals 實作清單:
== 檢查同一引用instanceof 檢查型別Object,加 @OverrideClass 物件| 載入器 | 來源 | 父載入器 |
|---|---|---|
| Bootstrap | rt.jar 核心類庫 | 無(C++ 實現) |
| Extension | jre/lib/ext 或 java.ext.dirs | Bootstrap |
| System (Application) | classpath | Extension |
| Custom | 使用者自定義 | System |
雙親委派 (PDM):請求父載入器 → 父無法載入 → 子自行載入。優勢:避免核心類被竄改、確保類載入唯一性。
char 佔 2 bytes (16 bits),涵蓋基本多文種平面 (BMP) 所有漢字InputStreamReader/OutputStreamWriter(適配器模式)| 維度 | 抽象類 | 介面 |
|---|---|---|
| 實例化 | 不可 | 不可 |
| 建構子 | 可有 | 不可 |
| 方法 | 抽象 + 具體 | 全抽象 (Java 8 前) |
| 成員存取 | private/protected/public | 隱含 public |
| 成員變數 | 變數/常數 | 隱含 static final 常數 |
| 繼承/實作 | 單繼承 | 多實作 |
Static Nested Class:無需外部類實例即可 new Outer.Nested()Inner Class:需 new Outer().new Inner(),持有外部類引用new Outer().new Inner()(無 this)Session (一級快取) 未 close/flush、靜態集合持有物件引用、監聽器未移除OutOfMemoryError、Disk Paging、效能急劇下降abstract 不能與 static、native、synchronized 共存。原因:需子類重寫,但 static/native/synchronized 涉及具體實現細節,互斥。
static 變數:屬於類,全類共享單一拷貝new 後存取static 方法不可直接呼叫非 static 方法/欄位(無 this)Cloneable + 重寫 clone()(淺拷貝,需手動深拷貝)Serializable + 序列化/反序列化(**真正深度克隆**,編譯期型別檢查,優於 clone())System.gc() / Runtime.gc()(僅建議,JVM 可忽略)-Xms/Xmx、-Xmn、-XX:+PrintGCDetails、-XX:NewRatio、-XX:SurvivorRatio、-XX:MaxTenuringThreshold
String s = new String("xyz");
// 2 個物件:"xyz" (常量池) + new String() (Heap)
class A { static { print(1); } { print(2); } A() { print(3); } }
class B extends A { static { print(4); } { print(5); } B() { print(6); } }
new B(); new B();
// 輸出:1 4 2 3 5 6 2 3 5 6
// 靜態區塊僅類載入時執行一次
Integer.parseInt()、Integer.valueOf()String.valueOf()、"" + valreverse(s) = reverse(s.substring(1)) + s.charAt(0)new String(s.getBytes("GB2312"), "ISO-8859-1")系列導航:Java 基礎面試題(一) | Java 基礎面試題(二) | Java 基礎面試題(三)