博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
创建正真的Java不可变类
阅读量:5928 次
发布时间:2019-06-19

本文共 3387 字,大约阅读时间需要 11 分钟。

如果需要设计一个不可变类,尤其要注意其引用类型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

你可能感兴趣的文章
设计模式--Simple Factory 模式
查看>>
Web基础架构:负载均衡和LVS
查看>>
史上最全开源大数据工具汇总
查看>>
伴随矩阵 和 余子式, 行列式的关系
查看>>
applications over the unaudited use restrictions!
查看>>
Material Design学习之 Sliders(详细分析,悬空气球显示进度值,附带Eclipse可以jar)...
查看>>
[LeetCode]75.Sort Colors
查看>>
Android 自定义Dialog类,并在Activity中实现按钮监听事件
查看>>
String、StringBuffer、StringBuilder区别
查看>>
Android SnackBar
查看>>
VMware vSphere虚拟化之-组件及用途
查看>>
Android 多包名打包应用
查看>>
微信小程序布局基础
查看>>
VNC重启无法使用问题(原创)
查看>>
Spring Cloud eureka 高可用
查看>>
随遇而安——状态模式
查看>>
如何高效阅读Github源代码
查看>>
吴颖二:12.14 美联储加息会否影响到美国税改的“影响”
查看>>
Druid Segment Balance 及其代价计算函数分析
查看>>
伪静态配置apache 和nginx
查看>>