zoukankan      html  css  js  c++  java
  • 创建正真的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类也是不可变的类。

  • 相关阅读:
    mysql基础整理01
    继承、接口、static、abstract
    重载与重写
    单例模式
    我的程序人生
    Idea的Maven项目引入模块
    测试单元测试完毕关闭jvm
    java线程
    logback日志的美化
    Netty中消除开始的日志消息修改日志级别
  • 原文地址:https://www.cnblogs.com/bluepoint2009/p/create-immutable-class.html
Copyright © 2011-2022 走看看