Java中类的访问控制修饰符public与default区别及选择
作者:技术拾光时间:2026-07-21 07:58:03浏览:172
在Java中,类的访问控制修饰符public允许跨包访问,default则仅限包内可见。选择依据是类是否被其他包使用:对外暴露的用public,内部协作的用default,从而避免API过度暴露或访问失败,保证封装性与安全性。
在 Java 中,选择 public 还是 default 访问控制修饰符,核心取决于该类是否需要被其他包的代码使用。如果需要跨包访问,必须使用 public;如果仅在当前包内使用,default 更加安全且合理。

public 类:面向外部,开放使用
当类被声明为 public,相当于明确标注了“对外服务”的用途。工具类(如 StringUtils)、实体类(如 User)、接口实现类(如 ArrayList)等,只要其他模块需要实例化或继承该类,就必须将其设为 public。
- 一个源文件中最多只能有一个 public 类,且文件名必须与类名完全一致(大小写敏感)。
- 可以被任意包中的任意类访问,包括继承、实例化、反射调用等操作。
- 适合定义 API 层、框架暴露的类型以及被广泛复用的核心类。
default 类:包内协作,隐藏实现
不加任何修饰符即为 default,也称为包私有。这类类在包外自然“隐身”,是封装内部逻辑的理想选择,例如包内的辅助类、状态枚举、私有异常、测试专用类等。
- 只能被同一个包下的其他类访问,跨包时不可见(编译会直接报错)。
- 不限制一个文件中能定义几个 default 类,也不强制文件名与类名匹配。
- 适合实现细节类或仅供本包内协调使用的类型,避免暴露不必要的接口。
常见误用场景提醒
新手最容易犯的错误,是习惯性将所有类都写成 public,结果导致 API 泛滥、依赖混乱、重构困难。反之,若将本该对外提供的类设为 default,则会导致调用方编译失败。例如 Spring 的 @Service 类若未设为 public,注入时会因无法访问构造器而报错。
- 框架扫描的类(如 Spring Bean、JUnit 测试类)通常要求 public,否则反射会失败。
- 测试类(后缀为 Test)建议使用 public,方便测试框架加载。
- 包内工具类(如 JsonHelper)若只被同包内的 Service 使用,采用 default 即可。
判断流程图(一句话版)
问自己三个问题:
- 这个类会被其他包的代码 new 或 extends 吗?→ 是 → 用 public
- 它只是帮本包里几个类干活的“幕后人员”吗?→ 是 → 用 default
- 它将来可能被抽成独立模块或 SDK 吗?→ 是 → 优先 public,预留扩展性
