Java 提供 public、protected、default (package-private)、private 四層級可見性,橫跨「同一類別」「同一套件」「不同套件子類別」「不同套件非子類別」四維度:
| 存取位置 | public | protected | default | private |
|---|---|---|---|---|
| 同一類別內 | ✅ | ✅ | ✅ | ✅ |
| 同一套件其他類別 | ✅ | ✅ | ✅ | ❌ |
| 不同套件子類別 | ✅ | ✅ | ❌ | ❌ |
| 不同套件非子類別 | ✅ | ❌ | ❌ | ❌ |
default 無關鍵字,類別/成員未加修飾詞即為套件私有。protected → 子 public 合法,反之非法)。com.company.project.moduleUserService、OrderController.java 首行必須為 package 宣告,缺省套件僅供測試臨時使用。// 檔案路徑:src/testPackage/Test.java
package testPackage;
public class Test {
public static void main(String[] args) {
mNode node = new mNode(); // 同套件類別直接可見
node.print("hello");
}
}
編譯部署指令:
# 自動依套件結構產生目錄並輸出 class 檔
javac -d . Test.java
# 從套件根目錄執行(完整限定類別名)
java testPackage.Test
java.util.Date vs java.sql.Date),避免全域命名空間汙染。default/protected 實現「套件內可見、對外隱藏」的封裝邊界。| 語法 | 語意 | 效能影響 | 適用場景 |
|---|---|---|---|
import java.util.Vector; | 單一類別匯入 | 編譯期解析,零執行期成本 | 精確控制、避免命名衝突 |
import java.awt.*; | 套件下所有 public 類別 | 同單一匯入,不會載入未使用類別 | 大量使用該套件核心類別 |
import static java.lang.Math.*; | 靜態匯入(JDK 5+) | 同單一匯入 | 常數/工具方法頻繁呼叫 |
import java.awt.F*; 通配符僅能匹配完整類別名,不支援前綴匹配。import java.*; 無法遞迴匯入子套件,java.util 需單獨匯入。import 僅告知編譯器「去哪裡找型別定義」,不會 將位元組碼內嵌至當前類別,不增加 class 檔體積。package → import → 類別定義。String、System、Thread、Exception 等核心類別無需 import 直接使用。java.awt.Font font = new java.awt.Font(...); 適用於偶爾使用、避免命名衝突。import java.util.*;。java.util.Date vs java.sql.Date 同時出現時,必須寫全名區分。module-info.java 宣告模組依賴、導出套件、開放反射存取,實現強封裝:
module com.myapp.core {
requires java.sql;
requires transitive java.logging;
exports com.myapp.core.api;
opens com.myapp.core.internal to com.myapp.plugins;
}
模組系統將「套件可見性」提升為「模組可見性」,解決傳統 Classpath 地獄與內部 API 洩漏問題,大型專案強烈建議遷移。