Java防止越权调用的关键是分层控制与最小权限原则:顶层类仅public或包私有;成员字段必须private(建议final);方法按需设public/protected/private;getter需防御性拷贝或返回不可变视图。

Java 中防止越权调用,关键不在“类可见性”本身,而在于**分层控制 + 最小权限原则**:类的可见性(public/default)决定谁能“看到并实例化这个类”,但真正防止越权操作的是对类内部成员(字段、方法)施加严格的访问修饰符,并配合设计约束。
类本身的可见性控制
顶层类只有两种合法修饰符:
-
public:必须与文件同名,可被任意包访问。适合对外暴露的 API 类(如
java.util.ArrayList)。 -
无修饰符(default / 包私有):仅本包内可见。这是更安全的默认选择——比如工具类
StringUtils、内部实体DatabaseConfig,不希望被外部依赖,就别加public。
⚠️ 注意:protected 和 private 不能用于修饰顶层类(编译报错),它们只适用于类的成员。
成员变量必须用 private 封装
越权修改几乎都发生在字段层面。只要字段不是 private,就可能被绕过逻辑直接篡改:
立即学习“Java免费学习笔记(深入)”;
- 字段设为
public或protected:外部可直接赋值,比如user.age = -5,校验形同虚设。 - 字段设为
default:同包内任意类都能改,包一膨胀,约束就失效。 - 字段设为
private:编译器强制拦截所有类外直接访问,obj.field = x或obj.field全部编译失败。
搭配 final(如 private final String id)可进一步锁定不可变状态。
方法访问权限要按需收紧
方法是数据的操作入口,其修饰符决定了谁有权触发行为:
-
对外服务方法:用
public,但内部必须校验参数、检查状态(如权限 token、业务规则)。 -
供子类扩展的方法:用
protected,子类可重写,但包外非子类无法调用。 -
纯内部逻辑方法:一律
private,比如数据格式化、缓存清理等,绝不暴露。 - 避免把 setter 设为
public却不做校验;敏感操作(如deleteAll())应加权限注解或运行时鉴权,不能只靠修饰符。
配合不可变返回与防御性拷贝
private 只防字段重赋值,不防内容篡改——尤其对集合、数组、可变对象:
- getter 返回
new ArrayList(this.items)而非原始引用。 - 返回
Collections.unmodifiableList(list)或使用ImmutableList。 - 构造器接收集合参数时,做深拷贝或立即转为不可变结构。
否则外部拿到引用后调用 list.add(...),依然会污染内部状态。


















