// 文件:Nov2016/use01/Test.java
package Nov2016.use01;
class Test { // 無修飾符 = package-private (包私有)
public String getString() {
return "123";
}
}
// 文件:Nov2016/Ques1121.java
package Nov2016;
import Nov2016.use01.Test; // 嘗試導入包私有類
public class Ques1121 {
public static void main(String[] args) {
Test test = new Test(); // 編譯錯誤!
System.out.println(test.getString());
}
}
上述程式碼能否編譯通過?
無法編譯通過,編譯器將報錯:
error: Test is not public in Nov2016.use01; cannot be accessed from outside package
import Nov2016.use01.Test;
^
| 修飾符 | 同類 | 同包 | 子類(異包) | 異包非子類 |
|---|---|---|---|---|
public | ✅ | ✅ | ✅ | ✅ |
protected | ✅ | ✅ | ✅ | ❌ |
| 無修飾符 (package-private) | ✅ | ✅ | ❌ | ❌ |
private | ✅ | ❌ | ❌ | ❌ |
public 或 無修飾符 (package-private)。Test 類無修飾符,故為包私有。Nov2016.use01 包外的代碼 (如 Nov2016.Ques1121) 無法導入、實例化、引用該類。import Nov2016.use01.Test 直接報錯。getString() 是 public,類本身不可見,方法也無法被外部調用。// Nov2016/use01/Test.java
package Nov2016.use01;
public class Test { // 添加 public
public String getString() {
return "123";
}
}
// Nov2016/use01/Ques1121.java
package Nov2016.use01; // 同包
public class Ques1121 {
public static void main(String[] args) {
Test test = new Test(); // 同包可直接訪問,無需 import
System.out.println(test.getString());
}
}
// Nov2016/use01/TestService.java (公共介面)
package Nov2016.use01;
public interface TestService {
String getString();
}
// Nov2016/use01/TestImpl.java (包私有實現)
class TestImpl implements TestService {
public String getString() { return "123"; }
}
// Nov2016/use01/TestFactory.java (公共工廠)
public class TestFactory {
public static TestService create() { return new TestImpl(); }
}
// Nov2016/Ques1121.java (外部調用)
package Nov2016;
import Nov2016.use01.TestFactory;
import Nov2016.use01.TestService;
public class Ques1121 {
public static void main(String[] args) {
TestService service = TestFactory.create();
System.out.println(service.getString());
}
}
publicprivate/protected 修飾,外部類可訪問私有內部類module-info.java 中 exports 控制包導出,比修飾符更精細Class.forName("Nov2016.use01.Test") 可加載,但 newInstance() 仍會拋出 IllegalAccessException (除非 setAccessible(true))