| 特性 | 抽象類別 | 介面 |
| 方法實作 | 可有抽象方法也可有具體方法 | JDK 8 前全為抽象方法;JDK 8+ 可有 default/static 方法 |
| 變數 | 可有實例變數、靜態變數、常數 | 只能有 public static final 常數 |
| 建構子 | 可有建構子(供子類別呼叫) | 不可有建構子 |
| 繼承/實作 | 單繼承(extends) | 多實作(implements) |
| 存取修飾符 | 方法可為 protected、public 等 | 方法隱含 public |
內部類別:Static Nested Class vs Inner Class
- Static Nested Class:靜態內部類別。建立實例不需要外部類別實例,無法直接存取外部類別非靜態成員。
- Inner Class (非靜態):內部類別。建立實例需依附外部類別實例,可直接存取外部類別所有成員(含 private)。
- Anonymous Inner Class:匿名內部類別。無名稱,不可
extends 其他類別,但可 implements 一個介面(或繼承一個類別)。
執行緒與同步機制
sleep() vs wait()
sleep():Thread 靜態方法。讓目前執行緒休眠指定時間,**不釋放鎖**。時間到進入可執行狀態,不保證立即執行。
wait():Object 實例方法。必須在 synchronized 區塊/方法中呼叫,**釋放鎖**,進入等待池。需 notify()/notifyAll() 喚醒進入鎖池競爭鎖。
啟動執行緒:run() 還是 start()?
必須呼叫 start()。start() 會建立新執行緒並使其進入可執行狀態,JVM 會在適當時機呼叫 run()。直接呼叫 run() 只是普通方法呼叫,不會建立新執行緒。
synchronized 方法的鎖行為
一個物件的 synchronized 方法同一時間只能被一個執行緒存取。其他執行緒嘗試存取該物件的**任何** synchronized 方法都會阻塞(因為鎖是物件級別的)。非 synchronized 方法不受影響可並發存取。
基礎語法與陷阱題
String 建立物件數量
String s = new String("xyz");
建立**兩個**物件:字串常量池中的 "xyz"(若不存在)和堆上的新 String 物件 s 參考。
Math.round() 行為
Math.round(11.5) → 12 (long)
Math.round(-11.5) → -11 (long)
規則:floor(x + 0.5),負數向零方向捨入。
short 型別運算陷阱
short s1 = 1; s1 = s1 + 1; // 編譯錯誤:s1+1 提升為 int,需強制轉型 (short)(s1+1)
short s1 = 1; s1 += 1; // 正確:複合指派運算子隱含強制轉型
陣列與 String 的 length
- 陣列:
length 是**屬性**(非方法)
- String:
length() 是**方法**
equals() vs ==
==:比較基本型別值、參考型別記憶體位址(是否同一物件)
equals():Object 預設比較位址;通常被覆寫比較**內容**(如 String、包裝類別、集合)。
Set 判斷重複依據是 equals(),且要求 hashCode() 一致。
參數傳遞:值傳遞還是參考傳遞?
**Java 只有值傳遞**。物件參考的值(記憶體位址)被傳遞。方法內可修改物件內容(屬性),但無法改變呼叫端的參考變數指向(如 obj = new Obj() 不影響外部)。
switch 支援型別
switch(expr) 中 expr 必須為 int、short、char、byte 或其包裝類別、enum(JDK 5+)、String(JDK 7+)。不支援 long、float、double、boolean。
經典程式碼錯誤分析
1. abstract 方法不能有方法體
abstract class Name {
private String name;
public abstract boolean isStupidName(String name) {} // 錯誤:應以分號結尾,無大括號
}
2. 區域變數不能有存取修飾符
void doSomething() {
private String s = ""; // 錯誤:區域變數前不能加 private/public/protected
// 可用 final 修飾區域變數
}
3. abstract 方法不能是 private
abstract class Something {
private abstract String doSomething(); // 錯誤:abstract 給子類別實作,private 會封鎖
}
4. final 參數不可修改
public int addOne(final int x) {
return ++x; // 錯誤:x 是 final,不可修改
}
5. final 參考變數 vs 物件內容
public void addOne(final Other o) {
o.i++; // 正確:修改物件屬性,參考 o 未變
// o = new Other(); // 錯誤:修改參考
}
6. 實例變數預設值
class Something {
int i; // 預設值 0
public void doSomething() { System.out.println("i = " + i); }
}
7. final 實例變數需顯式初始化
class Something {
final int i; // 錯誤:無預設值,必須在建構子結束前賦值
// 修正:final int i = 0; 或在建構子初始化
}
8. static 方法不能直接呼叫 non-static 方法
public static void main(String[] args) {
Something s = new Something();
System.out.println(doSomething()); // 錯誤:應為 s.doSomething()
}
9. 類別名稱與檔名關係
只有 public class 必須與檔名相同。非 public 類別可不同名。
10. 介面變數隱含 public static final
interface Rollable extends Playable, Bounceable {
Ball ball = new Ball("PingPang"); // 實為 public static final Ball ball = ...
}
class Ball implements Rollable {
public void play() {
ball = new Ball("Football"); // 編譯錯誤:final 變數不可重新指派
}
}
Singleton 模式實作
餓漢式(執行緒安全、類別載入時建立)
public class Singleton {
private Singleton() {}
private static final Singleton INSTANCE = new Singleton();
public static Singleton getInstance() { return INSTANCE; }
}
懶漢式雙重檢查鎖定(JDK 5+ volatile 保證可見性)
public class Singleton {
private Singleton() {}
private static volatile Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) instance = new Singleton();
}
}
return instance;
}
}
靜態內部類別式(推薦:延遲載入、執行緒安全、簡潔)
public class Singleton {
private Singleton() {}
private static class Holder { static final Singleton INSTANCE = new Singleton(); }
public static Singleton getInstance() { return Holder.INSTANCE; }
}
常見 RuntimeException
NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException、IllegalArgumentException、IllegalStateException、NumberFormatException、NoSuchElementException、ConcurrentModificationException、UnsupportedOperationException 等。
Error vs Exception
- Error:JVM 無法恢復的嚴重問題(如
OutOfMemoryError、StackOverflowError),程式不應嘗試捕捉處理。
- Exception:程式設計或實作問題導致的異常狀況,分為受檢異常(編譯期強制處理)和非受檢異常(RuntimeException 子類)。
- 上一篇文章: JDBC 核心指南:Java 資料庫連接技術全解析
- 下一篇文章: JDK 5 Enum 枚舉類型深度解析與最佳實踐
Copyright ©
程式碼之家 All Rights Reserved