題幹與適用場景
團隊希望減少 Java 小工具和範例程式中的重複 import,計畫在 Java 25 使用 Module Import Declarations。請說明它的語義、適用邊界、衝突處理和遷移驗證,不要只複述新語法。
面試官考察點
- 是否知道模組匯入會匯入模組匯出的套件,而不是任意內部型別。
- 是否能解釋模組描述元、可讀性關係和編譯期名稱解析的影響。
- 是否考慮同名型別衝突、明確單型別匯入優先級和 API 可讀性。
- 是否能提出相容舊 JDK、建置工具和程式碼審查的遷移策略。
回答前需要釐清的問題
- 程式碼的最低執行 JDK 是多少,建置鏈是否已支援 Java 25 語法?
- 目標檔案是教學範例、命令列小工具還是長期維護的模組化服務?
- 相依模組是否穩定匯出所需套件,是否存在多個套件提供同名公開型別?
- 團隊更在意減少樣板程式碼,還是希望每個依賴都能被讀者一眼稽核?
30 秒回答框架
我會先確認專案編譯和執行都在 Java 25 及以上,再把 import module 視為對模組匯出 API 的批次匯入,而不是萬用字元。它適合依賴穩定、範圍清楚的小型程式;公共函式庫和安全敏感程式碼仍要評估明確匯入的可讀性。遷移時編譯所有來源集,刻意加入同名型別測試,檢查明確匯入覆蓋規則,並保留舊 JDK 的回退分支或明確升級門檻。
分步驟深入解答
1. 先理解匯入範圍
JEP 511 在 Java 25 將模組匯入宣告標準化。宣告會把目標模組匯出的套件中可存取型別帶入目前編譯單元;未匯出的內部套件不會因這個語法變得可見。模組系統的 requires 和可讀性關係仍決定程式碼能否存取這些型別。
2. 辨識它與萬用字元匯入的差異
模組匯入以模組為邊界,可能涵蓋多個匯出套件;套件萬用字元匯入只涵蓋一個套件。以下語法範例必須在啟用 Java 25 的編譯器中驗證:
import module java.base;
class Tool {
static void printSize(String value) {
System.out.println(value.length());
}
}模組匯入不會匯入模組未匯出的實作細節,也不會取代模組描述元中的相依宣告。
3. 處理名稱衝突
不同匯出套件可能包含同名型別。遇到歧義時,使用單型別匯入或完全限定名表達意圖;不要依賴編譯器偶然選擇。明確匯入應成為團隊約定,讓審查者能看出關鍵 API 來自哪個套件。還要測試 java.lang 等隱式可見型別與模組匯入同名時的優先級。
4. 規劃遷移與相容
先在獨立來源集啟用 Java 25 編譯,再執行完整測試、靜態檢查和打包任務。檢查 IDE、格式化器、靜態分析器和增量編譯器是否理解新語法;函式庫專案要評估消費者的最低 JDK。若必須支援舊版本,可繼續使用明確匯入,或讓新語法只存在於 Java 25 專用模組,避免執行時升級風險擴散到所有服務。
高品質示範回答
我會先確認最低 JDK、編譯器和建置工具都支援 Java 25。import module 按模組邊界匯入其匯出套件中的可存取型別,不能存取未匯出的內部實作,也不能取代 requires。它適合小型工具、範例或匯出面穩定的模組;公共函式庫和高稽核程式碼要權衡樣板減少與依賴可見性。遷移時對同名型別、java.lang 衝突和明確匯入優先級做編譯測試,並檢查 IDE、靜態分析和打包鏈。舊 JDK 消費者仍使用明確匯入,直到升級門檻和相容矩陣被驗證。
常見錯誤
- 把模組匯入誤解成可以存取模組內部所有套件。
- 認為它會自動增加模組的
requires或改變模組可讀性。 - 忽略不同匯出套件的同名型別,導致編譯歧義或錯誤 API。
- 只升級本地 JDK,沒有驗證 CI、IDE、格式化器和打包工具。
- 在公共函式庫中盲目使用批次匯入,降低依賴稽核和跨版本相容性。
- 把 Java 25 語法發布給仍執行舊 JDK 的消費者。
追問及應對
模組匯入與套件萬用字元該怎麼選?
模組匯入適合希望按模組邊界表達依賴、且匯出面穩定的程式碼;套件萬用字元更局部、更容易稽核。公共 API 或同名型別較多時優先明確單型別匯入,避免隱藏依賴。
遇到同名型別時編譯器怎麼處理?
如果多個匯入候選都能匹配,程式會產生歧義。用單型別匯入或完全限定名消除衝突,並把選擇寫進程式碼審查規範;不要依賴匯入順序解決問題。
如何支援 Java 21 和 Java 25?
為不同執行時建立清楚的編譯矩陣。共用原始碼繼續使用明確匯入;只有 Java 25 專用來源集使用模組匯入,並在發布前驗證位元組碼、測試和相依方的最低版本。