真正封装需private字段+校验型setter+不可变副本getter:setter校验输入(如age∈(0,150)),getter返回防御性拷贝(如unmodifiableList),禁用全量set方法,因String等不可变类可public final而List等可变容器必须控制访问路径。
Java里怎么用private+getter/setter才算真正封装
封装不是加个
就完事,关键在“控制访问路径”。很多代码把字段设成
,但
无脑透传、
直接返回可变对象引用,等于没封。
字段必须
,连
都不行——子类访问会绕过校验逻辑
里要校验:比如
得检查
,不能只做赋值
返回不可变副本:如果字段是
,别直接return原集合,改用
或
避免提供“全量修改”方法:比如不要写
,而应拆成
、
等带校验的单点方法
为什么String、LocalDateTime这类字段可以直接public final但List不行
因为
和
是不可变类(immutable),即使你把它设为
,外部也无法修改其内部状态;但
、
、数组这些可变容器,一旦暴露引用,调用方就能add/remove/clear,彻底破坏封装边界。
安全做法:
,然后只提供
和
错误示范:
—— 这会让外部随意修改内部列表
注意
只保证引用不变,不保证对象内容不变。对可变对象,
只是第一道弱防线
IDE自动生成getter/setter时最常漏掉的三件事
IntelliJ或Eclipse一键生成的
/
默认不处理校验、深拷贝、空值防御,直接用等于埋雷。
字符串字段的
没判
:应该写
集合字段的
没做防御性拷贝:生成后手动替换成
数值字段没范围校验:比如
字段,生成的
应补上
当需要序列化(JSON/DB)时,封装和Jackson/Hibernate怎么共存
框架需要访问字段或调用
,但又不能破坏封装逻辑——这时候别开后门,用标准机制解耦。
Eclipse导入Android或其他的JAVA项目的正确方法 WORD版
本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
下载
立即学习
“
Java免费学习笔记(深入)
”;
Jackson:用
和
标注全参构造器,让反序列化走构造路径,避开无校验的
Hibernate:用
强制它通过
/
访问,确保校验逻辑生效
禁止用
屏蔽字段再另写“工具方法”:那等于在封装墙上凿洞,后续维护者根本看不出数据流从哪进哪出
如果必须用字段直访(如Lombok的
),至少加上
并手写带校验的public方法
真正的封装难点不在语法,而在每次新增一个字段时,是否条件反射地问自己:“这个值可能被谁改?改的时候有没有业务规则要 enforce?”——漏掉一次,数据就可能从那个口子开始腐烂。
privateprivatesettergetterprivateprotectedsettersetAge(int age)age > 0 && age < 150getterListnew ArrayList<>(this.items)Collections.unmodifiableList(this.items)setUser(User user)setName()setEmail()StringLocalDateTimepublic finalListMapprivate final List tags = new ArrayList<>(); addTag(String tag)getTagsCopy()public List getTags() { return tags; } finalfinalgettersettersetternullif (name == null) throw new IllegalArgumentException("name cannot be null");getterreturn Collections.unmodifiableList(new ArrayList<>(this.items));scoresetScore(int score)if (score < 0 || score > 100) throw ...setter@JsonCreator@JsonPropertysetter@Access(AccessType.PROPERTY)gettersetter@JsonIgnore@Data@Setter(AccessLevel.PRIVATE)