Java成员变量封装需以private为起点,通过修饰符控制访问、getter/setter校验输入、防御性拷贝防篡改、静态字段谨慎暴露并线程安全,构建完整可控的数据边界。

Java 成员变量的封装不是简单加个 private 就完事,而是围绕“谁该访问、怎么访问、改了会怎样”构建一套可控的数据边界。核心在于用对修饰符、补上校验、防住引用泄露,让字段既安全又可用。
私有化是起点,不是终点
把字段声明为 private 确实阻止了外部直接读写,但仅此一步远不够。它只是关上了门,没装锁、没设岗、也没检查进门的人带没带违禁品。
- 所有非必需暴露的字段都应默认
private,哪怕暂时没逻辑校验也要先封住 - 不要依赖“大家自觉不碰”,而要靠编译器强制拦截——
person.age = -5这种代码必须在编译期就报错 - 构造器或初始化块中要确保字段被合理赋值,避免对象创建后处于非法状态(如
name = null却没校验)
getter/setter 要带“守门人”逻辑
public 方法是外界唯一合法入口,它得承担全部责任:校验、转换、日志、甚至触发通知。
-
setAge(int age)不能只做赋值,必须判断范围(比如 0–150),越界就抛IllegalArgumentException,不静默吞掉错误 -
setName(String name)要拒绝null和空白字符串,用Objects.requireNonNull(name, "姓名不可为空")或!name.trim().isEmpty() - boolean 类型的 getter 命名为
isActive()而非getActive(),符合 Java Bean 规范,也更语义清晰
防御性拷贝防篡改
如果字段是可变对象(如 ArrayList、Calendar、数组),getter 返回原始引用等于把钥匙交出去——外部能绕过 setter 直接改内部状态。
立即学习“Java免费学习笔记(深入)”;
- 集合类建议用
Collections.unmodifiableList(new ArrayList(internalList))返回不可修改视图 - 日期类如
Date或LocalDateTime,getter 中返回新实例:return new Date(lastModified.getTime()) - 数组用
Arrays.copyOf(internalArray, internalArray.length),避免外部通过索引修改
静态字段封装要更谨慎
static 变量属于类,一份内存被所有实例共享。一旦暴露,破坏力比实例字段更大。
- 静态配置项(如重试次数)必须
private static,再配public static setMaxRetryCount(int)方法控制写入 - 缓存类列表不能写成
public static List<string> cache = new ArrayList()</string>,而应private static final List<string> CACHE = Collections.unmodifiableList(...)</string> - 涉及多线程修改时,优先用
AtomicInteger、ConcurrentHashMap替代普通类型,或在方法内加synchronized


















