FAQ:throw vs throws 核心差異
| 關鍵字 | 位置 | 語意 | 範例 |
throw | 方法體內 / 靜態初始化塊 / 建構子 | **拋出** 具體例外實例,中斷當前流程 | throw new IllegalArgumentException("id 不可空"); |
throws | 方法宣告 / 建構子宣告 | **宣告** 可能拋出的受檢例外類別,轉嫁處理責任給呼叫端 | public void save() throws IOException, SQLException |
實戰組合
public User findById(String id) throws UserNotFoundException, DataAccessException {
if (id == null || id.isBlank()) {
throw new IllegalArgumentException("id 不可空"); // 非受檢,無需 throws
}
try {
return userRepository.findById(id)
.orElseThrow(() -> new UserNotFoundException("找不到使用者: " + id));
} catch (SQLException e) {
throw new DataAccessException("資料庫查詢失敗", e); // 包裝原始例外保留堆疊
}
}
💡 原則:throw 是動作 (丟球),throws 是契約 (告知對方可能丟什麼球)。**受檢例外必須 throws 或 try-catch 處理**;非受檢例外 (RuntimeException 子類) 可選擇性宣告。
FAQ:JAR 打包完整指南
jar 命令語法
jar {c|t|x|u}[vfm0MiC] jar-file [manifest-file] [-C dir] files...
核心選項
| 選項 | 功能 | 常用組合 |
c | 建立新 JAR | cvf (建立+詳細輸出+指定檔名) |
t | 列出 JAR 內容 | tvf |
x | 解壓 JAR | xvf |
u | 更新現有 JAR | uvf |
v | 詳細輸出 | 幾乎總是加上 |
f | 指定 JAR 檔名 (後接檔名) | **必須**,否則讀寫 stdout/stdin |
m | 包含指定 Manifest 檔 | cvfm app.jar manifest.mf |
0 | 僅儲存不壓縮 | 資源檔 (圖片/音訊) 已壓縮時避免二次壓縮 |
M | 不建立預設 Manifest | 完全自訂 Manifest 時使用 |
C | 切換目錄後包含檔案 | cvf app.jar -C build/classes . -C src/main/resources . |
i | 產生索引資訊 (JAR Index) | 加速類別載入 (舊版優化,模組系統較少用) |
實戰範例
# 1. 簡單打包類別檔
jar cvf app.jar com/example/*.class
# 2. 含 Manifest (指定主類別、Class-Path)
# manifest.mf 內容:
# Manifest-Version: 1.0
# Main-Class: com.example.Main
# Class-Path: lib/dependency1.jar lib/dependency2.jar
jar cvfm app.jar manifest.mf -C build/classes . -C lib .
# 3. Spring Boot Fat JAR (由 maven-shade-plugin / spring-boot-maven-plugin 產生)
# 內含所有依賴,特殊啟動器 JarLauncher 解壓依賴至臨時目錄
java -jar app.jar
# 4. 模組化 JAR (JDK 9+)
# 含 module-info.class,支援 --module-path
jar cvf app.jar --main-class=com.example.Main -C build/classes .
Manifest 關鍵屬性
| 屬性 | 用途 | 範例 |
Main-Class | 可執行 JAR 進入點 | Main-Class: com.example.Application |
Class-Path | 相依 JAR 相對路徑 (空白分隔) | Class-Path: lib/json.jar lib/db.jar |
Module-Main-Class | 模組化應用主類別 | Module-Main-Class: com.example.Application |
Automatic-Module-Name | 非模組化 JAR 作為自動模組名稱 | Automatic-Module-Name: com.example.lib |
Implementation-Version | 建構版本資訊 | Implementation-Version: 1.2.3-SNAPSHOT |
優質 Java 學習資源精選 (2024 持續更新版)
官方權威
高品質技術站點
| 站點 | 特色 | 推薦專欄 |
| Baeldung | Spring 生態、Java 核心、測試、安全、Kotlin、實戰教程 | Spring Security、JPA、REST、併發、Jackson |
| InfoQ | 架構案例、新技術深度報導、QCon/ArchSummit 講稿 | 微服務、領域驅動、雲原生、效能工程 |
| Vlad Mihalcea | Hibernate/JPA/資料庫效能權威專家 | 連線池、批次處理、鎖、查詢優化 |
| Aleksey Shipilёv | JMH/JCStress/併發/JVM 內部核心貢獻者 | JMH 基準測試、記憶體模型、JIT 編譯 |
| Nicolai Parlog | Java 語言演進、模組系統、JShell、新特性深度解析 | JDK 9-21 新特性、模組化遷移 |
程式碼範例庫
中文優質社群
提問智慧
本期關鍵字
throw / throws — 異常拋出與宣告雙核心
jar cvfm — 打包可執行 JAR 標準組合
Manifest — JAR 中繼資料核心
MCVE — 最小可重現範例,提問黃金標準