`
d02540315
  • 浏览: 31402 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
社区版块
存档分类
最新评论

Java Immutable Class

阅读更多
Java Immutable Class[ From  ]

immutable object提供了极具价值的服务。由于他们保证自己的状态从构建之后就一定不再改变。因此他们天生具备多线程安全性。所以我们可以不必对它进行同步控制,这样可能能够提高些性能。但是实现immutable object时你必须实现clone(克隆)功能,而其代价可能不小。

要将一个类变成immutable是要通过多方面的合作才可能造就不变性:

1 将class中的所有数据声明为private。
2 只提供取值函数(getter),不提供设值函数(setter)。
3 声明class为final。
4 从获取器返回references to mutable object之前,先克隆(cloning)那些mutable object。
5 将传递给构造函数的reference to mutable object先clone
6 在构造函数中设定class内含的所有数据。


final class PinNumbers{

    private String acctowner;

   private int checkingApptPin;

   private int savingsAcctPin;

   PinNumbers(String owner,int cPin,int sPin){

     acctOwner = owner;

     checkingAccPin = cPin;

     savingsAcctPin = sPin;

   }

   public String accountOwner(){

     return acctOwner;

   }

  public int chechingPin(){


   return chechingAcctPin;

 }

  public int savingsPin(){

    return savingsAcctPin;

  }

}


这个class不需要克隆(clone)任何数据,因为其构造函数所接受的,或其取值函数(getter)所返回的,都只是基本类型和 reference to immutable object。基本类型不是对象,String class是恒常不变的,所以也不需要对它进行clone。

public class User {
    private String userName;
    private String userID;
    private int userNode;  
    
    public User(String userName, String userID, int userNode)
    {
        this.userName = userName;
        this.userID = userID;
        this.userNode = userNode;
    }
    
    public void setUserName(String userName)
    {
        this.userName = userName;
    }
    public String getUserName()
    {
        return userName;
    }
    
    public void setUserID(String userID)
    {
        this.userID = userID;
    }
    public String getUserID()
    {
        return userID;
    }
    
    public void setUserNode(int userNode)
    {
        this.userNode = userNode;
    }
    public int getUserNode()
    {
        return userNode;
    }
}



public final class DiskDriveInfo {
    private int driveSize;
    private String volumeLabel;
    private User driveShare;

    DiskDriveInfo(int size, String volLabel,User share)
    {
        driveSize = size;
        volumeLabel =volLabel;
        driveShare = share;
    }

    public int size()
    {
        return driveSize;
    }

    public String label()
    {
        return volumeLabel;
    }

    public User share()
    {
        return driveShare;
    }
}


上述DiskDriveInfo并不是immutable,因为在DiskDriveInfo可能改变user的值,例如:

public class ImmutableTest {
    public static void main(String[] args)
    {
        User user = new User("AAA", "04308032", 10001);        
        DiskDriveInfo info = new DiskDriveInfo(32, "mutable", user);        
        System.out.println(info.share().getUserName());
        user.setUserName("BBB");
        System.out.println(info.share().getUserName());
    }
}


上述代码的输出为:
AAA
BBB

想要将DiskDriveInfo类实现为immutable, 首先必须为User类实现clone()方法:

public class User implements Cloneable{
    private String userName;
    private String userID;
    private int userNode;  
    
    public User(String userName, String userID, int userNode)
    {
        this.userName = userName;
        this.userID = userID;
        this.userNode = userNode;
    }
    
    public void setUserName(String userName)
    {
        this.userName = userName;
    }
    public String getUserName()
    {
        return userName;
    }
    
    public void setUserID(String userID)
    {
        this.userID = userID;
    }
    public String getUserID()
    {
        return userID;
    }
    
    public void setUserNode(int userNode)
    {
        this.userNode = userNode;
    }
    public int getUserNode()
    {
        return userNode;
    }
    
    public Object clone()
    {
        try {
            User copy = (User)super.clone();
            return copy;
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }
    }
}

然后将DiskDriveInfo类的定义修改为:


public final class DiskDriveInfo {
    private int driveSize;
    private String volumeLabel;
    private User driveShare;

    DiskDriveInfo(int size, String volLabel,User share)
    {
        driveSize = size;
        volumeLabel =volLabel;
        driveShare = (User)share.clone();
    }

    public int size()
    {
        return driveSize;
    }

    public String label()
    {
        return volumeLabel;
    }

    public User share()
    {
        return (User)driveShare.clone();
    }
}


结果上述测试代码的输出将变成:
AAA
AAA

假如DiskDriveInfo类里面的不是一个user对象 而是一个Vector,里面保存了许多user对象。难道时调用Vector里面的clone()吗?可惜Vector克隆的不是整个的对象树,而是克隆了一个Vector但是里面的指向的user对象还是以前那个user对象的。这时候我们就需要深层克隆(Deep Cloning)

如:

class ShareVector extends Vector{

   ShareVector(int Size){

      super(size);

    }

  public Object clone(){

     ShareVector v = (ShareVector)super.clone();

    int size = size();

  for(int i=0;i<size;i++){

    User u = (User)(this.get(i));

     v.setElementAt((User)(u.clone()),i);

   }

  return v;

  }

}




或者在DiskDriveInfo中提供一个cloneVector(Vector)的方法好了。

private Vector cloneVector(Vector v){

   int size = v.size();

   Vector newVector = new Vector();

    for(int i=0;i<size;i++){

    newVector.add((User)(v.get(i)).clone));

   return newVector;

   }

}




总而言之,在实现了一个immutable class(不可变类)时,请遵守下列规则。

1、声明这个class为final。

2。声明所有的数据为private。

3。只提供取值函数(getter),不提供设值函数(setter)。

4、在构造函数中设置所有的instance数据。

5、如果函数返回references to mutable objects,请先克隆那些mutable objects。

6、如果函数接受references to mutable objects,请先克隆那些mutable objects。

7、如果缺省之浅层克隆(shallow clone)不能符合immutable object的正常行为,请实现出深层克隆(deep cloning)
分享到:
评论

相关推荐

    sample:核心 Java 示例

    样本 核心 Java 示例 1.Comparable Vs Comparator 2.Equal() & HashCode() 契约 3.Runtime Class 4.Uninstantiable Class 5.Immutable Class

    hibernate总结

    public class Dept implements java.io.Serializable { // Fields private Integer deptid; private String deptname; private Integer deptnum; private Integer actNum; private Date cdate; private Set ...

    Practical Java(中文版(繁体+简体))

    實踐62:區分interface、abstract class 和concrete class 212 實踐63:審慎㆞定義和實現immutable classes(不可變類) 213 實踐64:欲傳遞或接收mutable objects(可變對象)之object references 時,請實施clone...

    javabiginteger源码-Java:Java

    ##-----java.lang.Class类----- 5. 为什么说Class类不能被继承? 6. 为什么说我们不能 new Class()? 7. forName()中执行了什么流程? 8. toString()返回什么? 9. newInstance()中执行了什么? ##-----java.lang....

    jomni:Java 8 的对象映射器微型库

    // build the immutable and threadsafe JomniMapper JomniMapper mapper = new JomniBuilder () . build(); // ------ Simple type conversion examples ------- // // String to Long Long longVal = mapper . as...

    Java的六大问题你都懂了吗

     public class Demo {  private String s;  public Demo {  s = "Initial Value";}  }  而非  s = new String("Initial Value");  后者每次都会调用构造器,生成新对象,性能低下且内存开销大,并且...

    Java初学者都必须理解的六大问题

    因为String被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。请看下列代码:  String s = "Hello";  s = s + " world!";  s所指向的对象是否改变了呢?从本系列第一篇的结论很容易导出这个...

    Thinking in Java 4th Edition

    Java SE5 and SE6 .................. 2 Java SE6 ......................................... 2 The 4th edition........................ 2 Changes .......................................... 3 Note on the ...

    FactoryJill:用于将Java对象设置为测试数据的库

    工厂吉尔 用法 sourceCompatibility = 1.8 dependencies { ...} 特征 支持的: 定义可重复使用的工厂 覆盖字段 关联:将字段定义为其他... class, ImmutableMap . of( " make " , " ford " , " convertible " , false ,

    Scala for the Impatient 2nd (完整英文第二版 带书签)

    13.2 Mutable and Immutable Collections 173 13.3 Sequences 174 13.4 Lists 175 13.5 Sets 177 13.6 Operators for Adding or Removing Elements 178 13.7 Common Methods 180 13.8 Mapping a Function 182 13.9 ...

    Immutables-Android-Example:在Android和GSON上使用Immutables 2.0的示例

    @Value.Immutable public abstract class User { public abstract int id(); public abstract String username(); } 我们可以将其用作: User user = ImmutableUser.builder().id(1).username("olidroide")....

    汪文君高并发编程实战视频资源全集

    │ 高并发编程第一阶段28讲、线程生产者消费者的综合实战结合Java8语法.mp4 │ 高并发编程第一阶段29讲、如何实现一个自己的显式锁Lock精讲上.mp4 │ 高并发编程第一阶段30讲、如何实现一个自己的显式锁Lock精讲...

    汪文君高并发编程实战视频资源下载.txt

    │ 高并发编程第一阶段28讲、线程生产者消费者的综合实战结合Java8语法.mp4 │ 高并发编程第一阶段29讲、如何实现一个自己的显式锁Lock精讲上.mp4 │ 高并发编程第一阶段30讲、如何实现一个自己的显式锁Lock精讲...

    Scala程序设计(第2版)

    24.2.2 ClassTag、TypeTag与Manifest 457 24.3 Scala 的高级运行时反射API 458 24.4 宏 461 24.4.1 宏的示例:强制不变性 463 24.4.2 关于宏的最后思考 466 24.5 本章回顾与下一章提要 466 附录A...

    python3.6.5参考手册 chm

    PEP 487: Simpler customization of class creation PEP 487: Descriptor Protocol Enhancements PEP 519: Adding a file system path protocol PEP 495: Local Time Disambiguation PEP 529: Change Windows ...

    不可变的:注释处理器,用于创建不可变的对象和构建器。 感觉像番石榴的不可变集合,但对于常规值对象。 包括JSON,Jackson,Gson,JAX-RS集成

    阅读完整的文档,为 // Define abstract value type using interface, abstract class or annotation@Value . Immutablepublic interface ValueObject extends WithValueObject { // extend not-yet-generated ...

    hibernate3.6 文档(pdf 格式)

    1.1.2. The first class .......................................................................................... 3 1.1.3. The mapping file ...............................................................

Global site tag (gtag.js) - Google Analytics