Java中没有真正的“包私有”机制,default仅实现包级可见,无法阻止同名包不同模块/路径的访问或反射绕过;真正封装需依赖JPMS模块化exports控制、工厂模式隔离与运行时校验三层防护。

Java 中没有真正的“包私有”权限机制,default(不写修饰符)只是包级可见,不是封装保障。它无法阻止同名包下不同模块、不同路径的代码访问,更防不住反射调用。想靠 default 实现模块化封装,会误判风险边界。
default 访问权限的真实能力与局限
default 成员可在同一运行时包中被任意类访问——但“同一包”只看 package 声明,不看源码归属或构建路径。这意味着:
- Maven 多模块项目中,只要另一个模块也声明
package com.example.service;,就能直接调用你的 default 方法 - OSGi 或 JPMS 环境下,未导出的包若被其他模块以非法方式加载,default 成员仍可能暴露
-
AccessibleObject.setAccessible(true)可绕过所有访问修饰符,default 对反射毫无防御力
真正实现模块化封装:必须用 module-info.java 控制 exports
Java 9+ 的模块系统(JPMS)才是唯一能从架构层切断非法访问的手段。关键不是把类设为 default,而是控制“谁能看到这个包”:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 在
module-info.java中不exports某个包,该包内所有类(无论 public/default/private)对外部模块都不可见 - 即使类是 public,未导出的包也无法被 import、new 实例、甚至无法通过反射定位到类名
- 可精细控制:如
exports com.example.api to com.example.client,只允许指定模块使用
非模块化环境下的替代方案:工厂 + 接口 + 私有实现
若受限于 JDK 8 或旧框架,需靠设计收敛入口:
立即学习“Java免费学习笔记(深入)”;
- 核心逻辑类用 default 或 private static 内部类封装,不暴露构造器
- 顶层类提供 public static 工厂方法,返回接口类型(而非具体类)
- 接口中用 private 方法组织复用逻辑(Java 9+),避免 default 方法重复实现
- 必要时在工厂方法中用
StackWalker检查调用栈,确认调用方是否来自预期包
接口封装的双重加固:private 方法 + 模块导出
接口本身也能成为封装载体:
- Java 9+ 允许接口定义 private 方法,仅供本接口内的 default/static 方法调用,外部完全不可见
- 配合
exports控制该接口是否导出:未导出的接口,其 private 方法连存在都不被外部感知 - 这样形成两层防护:语言层隐藏实现细节,架构层隐藏接口本身

















