Java中 类的访问控制修饰符 public 与 default 区别如何选择

作者:袖梨 2026-07-21
选 public 还是 default,关键看是否需跨包访问:需对外暴露则用 public(如 API 类、框架 Bean),仅包内使用则用 default(如辅助类、私有实现),前者开放但受限于单文件单 public 类,后者安全灵活、利于封装。

public 还是 default,关键看这个类是否需要被其他包的代码使用。如果需要跨包访问,必须用 public;如果只在当前包内使用,default 更安全、更合理。

public 类:面向外部,开放使用

一个类声明为 public,意味着它被设计成对外提供服务的入口。比如工具类(StringUtils)、实体类(User)、接口实现类(ArrayList)等,只要别的模块要实例化或继承它,就必须是 public

  • 一个源文件里最多只能有一个 public 类,且文件名必须和类名完全一致(大小写敏感)
  • 可以被任意包中的任意类访问,包括继承、实例化、反射调用
  • 适合定义 API 层、框架暴露的类型、被广泛复用的核心类

default 类:包内协作,隐藏实现

不加任何修饰符就是 default(也叫包私有)。这类类天然“隐身”于包外,是封装内部逻辑的好选择,比如包内的辅助类、状态枚举、私有异常、测试专用类等。

  • 只能被同一个包下的其他类访问,跨包即不可见(编译直接报错)
  • 不限制一个文件中能有几个 default 类,也不强制文件名匹配
  • 适合实现细节类、仅供本包内协调使用的类型,避免暴露无关接口

常见误用场景提醒

新手容易把所有类都写成 public,结果导致 API 泛滥、依赖混乱、重构困难。反过来,如果把本该对外提供的类设为 default,会导致调用方编译失败,比如 Spring 的 @Service 类若没设 public,注入时会因无法访问构造器而报错。

立即学习“Java免费学习笔记(深入)”;

  • 框架扫描的类(如 Spring Bean、JUnit 测试类)通常要求 public,否则反射失败
  • 测试类(Test 后缀)建议 public,方便测试框架加载
  • 包内工具类(如 JsonHelper)若只被同包 Service 使用,用 default 即可

判断流程图(一句话版)

问自己三个问题:
– 这个类会被其他包的代码 new 或 extends 吗?→ 是 → 用 public
– 它只是帮本包里几个类干活的“幕后人员”?→ 是 → 用 default
– 它将来可能被抽成独立模块或 SDK?→ 是 → 优先 public,预留扩展性

相关文章

精彩推荐