關於「Android 隊列是否只能存 `Message` 物件」的疑問,答案很明確:**消息隊列 專存 `Message`,但廣義上的「隊列」資料結構可存放任意物件。** 混淆「Android 消息隊列」與「通用隊列資料結構」是誤區根源。
**結論**:若你在寫 `Handler` 機制、跨執行緒通訊、定時任務,**必須**將資料封裝進 `Message` (透過 `msg.obj` 或 `setData(Bundle)` 放入任意物件),再投遞給 `MessageQueue`。
當脫離 `Looper`/`Handler` 語境,純粹需要「先進先出」緩衝區時,使用 `java.util.Queue` 介面及其實現:
| 實現類 | 特性 | 適用場景 |
|---|---|---|
| LinkedList | 雙向鏈表,實現 `Deque`,非線程安全 | 單執行緒簡單 FIFO/LIFO,需頭尾雙向操作 |
| ArrayDeque | 循環陣列,容量自動擴容,非線程安全,**效能最優** | 高效能單執行緒隊列/棧,替代 `Stack`/`Vector` |
| PriorityQueue | 堆結構,按比較器排序,非線程安全 | 優先級隊列 (如任務調度、Dijkstra/A* 算法) |
| ConcurrentLinkedQueue | CAS 無鎖鏈表,**線程安全** | 多生產者多消費者 (MPMC) 高併發隊列 |
| LinkedBlockingQueue | 鎖 + 條件變數,有界/無界,**線程安全**,支援阻塞 `take`/`put` | 經典生產者-消費者模型、線程池任務隊列 |
| ArrayBlockingQueue | 陣列 + 雙鎖,**有界**、**線程安全**,阻塞操作 | 固定容量緩衝區、背壓控制 |
| DelayQueue | 優先隊列包裝 `Delayed` 物件,**線程安全**,到期才能取出 | 延遲任務、定時快取清理、重試機制 |
這些隊列**泛型 `E` 可為任意物件** (`String`、自定義 `Task`、`ByteBuffer` 等),與 `Message` 無任何關係。
你提到「隊列實質就是一個物件,對象和對象結合生成新的對象」,這是**組合模式** 的核心思想:
// 隊列物件 + 元素物件 = 隊列狀態 (新的邏輯整體)
Queue taskQueue = new LinkedBlockingQueue<>();
taskQueue.offer(new Task("A")); // Task 物件進入 Queue 物件
Task t = taskQueue.poll(); // 取出 Task 物件,Queue 狀態改變
這完全符合 OOP 原則,無需強行套用「Message 才能入隊」的限制。
**場景決定選型**:
釐清「框架專用隊列」與「通用資料結構隊列」的邊界,才能在 Android 複雜的併發架構中做出正確的架構決策。