在 Java 中,“保护 Field 字段”通常有两层含义:
下面从常见做法 → 进阶防护 → 注意事项系统说明。
private 修饰字段public class User {
private String name;
}
✅ 外部类无法直接访问
❌ 同一类内部仍可访问
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
if (name == null || name.isBlank()) {
throw new IllegalArgumentException("name 不能为空");
}
this.name = name;
}
}
✅ 可在设置时做校验
✅ 可控制只读 / 只写
finalprivate final String id;
✅ 只能赋值一次
✅ 适合“创建后不允许改”的字段
public final class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
✅ 无 setter
✅ 线程安全
✅ 防止外部修改
❌ 错误示例:
private List<String> list = new ArrayList<>();
public List<String> getList() {
return list; // 外部可修改
}
✅ 正确做法:
public List<String> getList() {
return Collections.unmodifiableList(list);
}
或返回副本:
return new ArrayList<>(list);
privateField f = User.class.getDeclaredField("name");
f.setAccessible(true);
f.set(user, "hack");
✅ Java 本身无法 100% 阻止反射(除非特殊环境)
module com.example {
exports com.example.api;
// 不导出内部类
}
✅ 反射无法访问未导出包
private transient String secret;
或自定义:
private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
throw new UnsupportedOperationException();
}
final classpublic final class Config {
private String key;
}
✅ 防止子类修改行为
private)public record User(String name, int age) {}
✅ 自动不可变
✅ 无 setter
| 目标 | 推荐方式 |
|---|---|
| 防止外部访问 | private |
| 控制修改 | getter/setter |
| 不可变 | final / record |
| 防反射 | Module |
| 防序列化 | transient |
| 防继承 | final class |
如果你有具体场景(如:防止反编译、防止框架反射、保护密码字段),可以告诉我,我可以给更针对性的方案。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。