当前位置: 首页 > news >正文

创建正真的Java不可变类

如果需要设计一个不可变类,尤其要注意其引用类型Field,如果其引用类型Field的类是可变的,就必须采取必要的措施来保护该Field所引用的对象不会被修改,这样才能创建真正的不可变类。

  1 class Name {
  2     private String firstName;
  3     private String lastName;
  4 
  5     public Name() {        
  6     }
  7 
  8     public Name(String firstName, String lastName) {
  9         this.firstName = firstName;
 10         this.lastName = lastName;
 11     }
 12 
 13     public void setFirstName(String firstName) {
 14         this.firstName = firstName;
 15     }
 16 
 17     public String getFirstName() {
 18         return this.firstName;
 19     }
 20 
 21     public void setLastName(String lastName) {
 22         this.lastName = lastName;
 23     }
 24 
 25     public String getLastName() {
 26         return this.lastName;
 27     }
 28 
 29     public String toString() {
 30         //return getClass().getName() + "@" + Integer.toHexString(hashCode());
 31         return getClass().getName() + "@[firstName=" + this.getFirstName() + ", lastName=" + this.getLastName() + "]";
 32     }
 33 }
 34 
 35 
 36 class Person1 { 
 37     private final Name name;
 38     
 39     public Person1(Name name) {
 40         this.name = name;
 41     }
 42 
 43     public Name getName() {
 44         return this.name;
 45     }
 46 
 47     public String toString() {
 48         //return getClass().getName() + "@" + Integer.toHexString(hashCode());
 49         return getClass().getName() + "@[name=" + this.getName() + "]";
 50     }
 51 }
 52 
 53 class Person { 
 54     private final Name name;
 55     
 56     public Person(Name name) {
 57         // 设置name为临时创建的Name对象,该对象的firstName和lastName与
 58         // 传入的name对象的firstName和lastName相同
 59         this.name = new Name(name.getFirstName(), name.getLastName());
 60     }
 61 
 62     public Name getName() {
 63         // 返回一个匿名对象,该对象的firstName和lastName与
 64         // 该对象里的name的firstName和lastName相同
 65         return new Name(name.getFirstName(), name.getLastName());
 66     }
 67 
 68     public String toString() {
 69         //return getClass().getName() + "@" + Integer.toHexString(hashCode());
 70         return getClass().getName() + "@[name=" + this.getName() + "]";
 71     }
 72 }
 73 
 74 public class PersonNameImmutableTest {
 75     public static void main(String[] args) {
 76         Name n1 = new Name("悟空", "孙");
 77         Person1 p1 = new Person1(n1);
 78         // Person对象的name的firstName值为“悟空”
 79         System.out.println(p1.getName().getFirstName());
 80         // 改变Person对象的name的firstName值
 81         n1.setFirstName("八戒");
 82         // 下面的输出为“八戒”,已经改变了原来的值“悟空”
 83         System.out.println(p1.getName().getFirstName());
 84         // 上面的运行结果说明,Person对象的name的firstName值已经被改变了,
 85         // 这就破坏了设计Person类的初衷
 86 
 87         //为了保持Person1对象的不可变性,必须保护好Person1对象的引用类型Field:name,
 88         //让程序无法访问到Person1对象的name Field,也就无法利用name Field的可变性来改变
 89         //Person1对象了。
 90         //为此,我们将Person1类该为Person类使用即可。
 91         Name n = new Name("悟空", "孙");
 92         Person p = new Person(n);
 93         // Person对象的name的firstName值为“悟空”
 94         System.out.println(p.getName().getFirstName());
 95         // 改变Person对象的name的firstName值
 96         n.setFirstName("八戒");
 97         // 这样,无论如何修改name的值,Person对象的name值不会改变,
 98         // 以下输出依然为“悟空”
 99         System.out.println(p.getName().getFirstName());
100     }
101 }

 

或者做如下修改:

将Name类的setter方法删除掉,这样Name类是不可变的类,Person1类也是不可变的类。

转载于:https://www.cnblogs.com/bluepoint2009/p/create-immutable-class.html

相关文章:

  • 创建Java不可变型的枚举类型Gender
  • hibernate 关系映射之 单向外键关联一对一
  • (转)原始图像数据和PDF中的图像数据
  • 基于HTML5技术的电力3D监控应用(四)
  • 创客运动引发第三次工业革命
  • php错误级别的设置方法
  • 案例参考:分享一个回报率1:3.5的热门竞价赚钱项目
  • paip.调试js 查看元素事件以及事件断点
  • UBUNTU 12.04安装ORACLE
  • 一段小代码
  • sso单点登录研究
  • 字符串处理总结之一(C#String类)
  • 独立游戏开发者如何利用媒体造势
  • iOS UITapGestureRecognizer手势和UIButton 以及UITabelView点击事件冲突
  • fork/join使用示例
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • 【跃迁之路】【735天】程序员高效学习方法论探索系列(实验阶段492-2019.2.25)...
  • 2019年如何成为全栈工程师?
  • Bootstrap JS插件Alert源码分析
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • C++入门教程(10):for 语句
  • CSS 专业技巧
  • css系列之关于字体的事
  • Django 博客开发教程 16 - 统计文章阅读量
  • js数组之filter
  • SpiderData 2019年2月25日 DApp数据排行榜
  • text-decoration与color属性
  • Travix是如何部署应用程序到Kubernetes上的
  • 番外篇1:在Windows环境下安装JDK
  • 仿天猫超市收藏抛物线动画工具库
  • 批量截取pdf文件
  • 前端每日实战:70# 视频演示如何用纯 CSS 创作一只徘徊的果冻怪兽
  • 视频flv转mp4最快的几种方法(就是不用格式工厂)
  • 想写好前端,先练好内功
  • 译米田引理
  • 自定义函数
  • [地铁译]使用SSD缓存应用数据——Moneta项目: 低成本优化的下一代EVCache ...
  • 组复制官方翻译九、Group Replication Technical Details
  • 昨天1024程序员节,我故意写了个死循环~
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • #pragam once 和 #ifndef 预编译头
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • #图像处理
  • (分类)KNN算法- 参数调优
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • (附源码)计算机毕业设计SSM疫情社区管理系统
  • (附源码)计算机毕业设计SSM智能化管理的仓库管理
  • (六)软件测试分工
  • (十六)Flask之蓝图
  • (收藏)Git和Repo扫盲——如何取得Android源代码
  • (一)SpringBoot3---尚硅谷总结
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • (转)http协议
  • (转)负载均衡,回话保持,cookie
  • (转)甲方乙方——赵民谈找工作