private仅对本类可见,编译期拒绝跨类访问,子类和同包类均不可访问;封装需配合getter/setter实现业务逻辑控制,而非仅靠private修饰。

private修饰符只对本类生效
Java中private的可见性范围最窄:仅限声明它的那个类内部可访问,连子类、同包其他类、外部类都不行。这不是“限制访问”,而是“不提供访问入口”——编译器在编译期就直接拒绝任何跨类调用,不会生成对应字节码。
常见错误现象:javac报错error: cannot find symbol或error: xxx has private access in YYY,说明你试图从非本类位置读写private字段或调用private方法。
- 子类不能继承
private成员,哪怕重写toString()时想调用父类private String name也不行 - 同包内其他类无法通过对象引用访问
obj.privateField,哪怕obj是该类实例 -
private方法不能被反射绕过(除非显式调用setAccessible(true),但这属于破坏封装的非常规手段)
封装不是靠private实现,而是靠它配合getter/setter
把字段设为private只是第一步;真正完成封装,得靠公开的public或protected方法来控制读写逻辑。比如校验、懒加载、事件通知等,都只能在这些方法里加。
示例:
立即学习“Java免费学习笔记(深入)”;
public class BankAccount {
private double balance;
public void deposit(double amount) {
if (amount > 0) { // 封装的逻辑在这里
balance += amount;
}
}
public double getBalance() {
return balance; // 不暴露原始字段,后续可加日志、缓存等
}
}
- 直接暴露
public double balance会导致余额被任意修改,失去业务约束 - 把
deposit()设为private也没意义——外界根本调用不到,无法完成存款动作 - getter/setter命名不是必须,但
getXXX()/setXXX()是JDK、Jackson、Hibernate等框架默认识别的约定
private不能修饰外部类或接口
Java语法规定:private只能用于成员变量、方法、内部类(包括匿名类和局部类),不能修饰顶级类或接口。写private class A {}在文件顶层会直接编译失败。
错误示例:error: modifier private not allowed here
- 如果想限制类的可见性,只能用
default(即不写修饰符),表示包私有 - 内部类可用
private,例如private static class Helper {},此时只有外层类能实例化它 - 接口中的方法默认是
public abstract,字段默认是public static final,加private会报错
private成员仍可能被反编译或反射暴露
运行时JVM不强制检查private——它只是编译期约束。通过java.lang.reflect可以绕过,只要目标类没做安全管理器限制。
示例:
立即学习“Java免费学习笔记(深入)”;
Field f = obj.getClass().getDeclaredField("balance");
f.setAccessible(true); // 关键一步:关闭访问检查
f.set(obj, 99999.0);
- 这不代表封装失效,而是说明封装是设计契约,不是安全屏障
- 生产环境应避免依赖反射修改
private状态;测试中慎用setAccessible(true),容易因字段名变更导致测试崩溃 - 模块化(Java 9+)下,即使反射也受
opens指令限制,未开放的包内private成员无法被外部模块反射访问
private切断了直连路径,但真正守住边界的,是你在getter/setter里写的那几行判断。










