`
d02540315
  • 浏览: 32289 次
  • 性别: 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)
分享到:
评论

相关推荐

    ImmutableObjects

    ### Immutable Objects in Java 在Java编程语言中,不可变对象(Immutable Objects)是一个重要的概念,尤其是在构建健壮、易于维护的应用程序时。本篇将基于提供的文件内容来深入探讨不可变对象的概念及其在Java中...

    有关于JAVA的一些PPT

    Java中的不可变类型(Immutable Types) 不可变类型是那些一旦创建后就不能改变其状态的对象。例如,使用`final`关键字声明的变量。 ### 8. 垃圾收集(Garbage Collector) Java拥有自动垃圾收集器,它负责回收...

    java面向对象之final修饰符.docx

    public ImmutableClass(String value) { this.value = value; } // 不允许创建子类 } ``` 总结,final关键字在Java中用于保证数据的不可变性、方法的不可重写以及类的不可继承,它是Java中实现封装性和安全性...

    详解Java编程中final,finalize,finally的区别

    public final class ImmutableClass { final int value; public ImmutableClass(int value) { this.value = value; } // final 方法 public final void doSomething() { // ... } } ``` 接下来是`...

    ikm_java_8.pdf

    写类使它们不可变(Immutable)**:不可变对象是指一旦创建后就不能改变其状态的对象。由于不可变对象没有可更改的状态,因此它们在多线程环境中不会出现同步问题。 - **c. 使用ThreadLocal变量**:`ThreadLocal`...

    Java中static、this、super、final用法.doc

    final class Immutable { private final int value; Immutable(int value) { this.value = value; } // value 不能被修改 } ``` 总结起来,`static`、`this`、`super`和`final`是Java中控制对象生命...

    java笔试面试题汇总

    - **描述**: 在一个`.java`源文件中可以包含多个类,但是只能有一个公共类(public class),并且该公共类的名字必须与文件名一致。 - **应用场景**: 当开发模块化较强的程序时,为了组织结构清晰,可能会在一个文件...

    Java搞懂的六个问题.txt

    在Java中,`String` 类型是不可变的(immutable),这意味着一旦一个 `String` 对象被创建后,它的值就不能被修改。例如,在文档中提到的 `"Hello"` 和 `"world!"` 的连接操作实际上创建了一个新的 `String` 对象,...

    Java常用工具类

    - `ClassUtils`:类和类加载相关的工具类,支持类名转换、获取类实例等。 4. **Guava库**:Google开源的一个Java库,包含大量核心库没有的功能,如集合、缓存、并发、I/O等。 - `Immutable Collections`:不可变...

    解决启动Azkaban报错问题:java.lang.NoSuchMethodError: com.google.common.collect.ImmutableMap.toImmutableMap

    在本文档的上下文中,错误发生在启动Azkaban时,具体表现为 `java.lang.NoSuchMethodError: com.google.common.collect.ImmutableMap.toImmutableMap`。Azkaban是一个开源的工作流执行器,用于调度和管理大数据处理...

    java oracle并发官方教程

    ### 不可变对象(Immutable Objects) 在并发编程中,不可变对象是不可更改的对象,一旦创建了它的实例,就不能修改它的状态。不可变对象可以提供线程安全保证,因为它们的状态不会在多个线程间改变。 ### 高级...

    50个左右的JAVA工具类,相对比较全

    在Java编程领域,工具类(Utility Class)是程序员日常工作中不可或缺的部分。这些工具类提供了许多通用功能,可以简化代码编写,提高开发效率。标题提到的"50个左右的JAVA工具类,相对比较全"表明这是一个集合了大量...

    java英文笔试

    In Java, the `String` class is a classic example of an immutable class. Once a `String` object is created, its value cannot be modified. Immutable objects are useful for ensuring thread safety and ...

    Java编程实验内容.ppt

    Java的编译环境包括Java源文件、Java编译器、Java字节码、Java解释器、JIT编译器、Runtime系统、Class加载器、字节码验证器、Java类库、操作系统和硬件。Java虚拟机(JVM)是Java的核心,负责解释字节码和管理Java...

    java常用的工具类

    `ImmutableCollections`提供不可变集合,保证数据安全。 3. **Java Collections Framework**: Java内置的集合框架包括List、Set、Map等接口,以及它们的实现类如ArrayList、HashSet、HashMap等。`Collections`工具...

    java&guava讲义.pptx

    * Java 编译过程:Java 编译生成 .class 文件(字节码文件),由 JVM 解释执行,具有跨平台性。 * Java 的优点:开源、多优秀的第三方框架(如 Guava、Spring、MyBatis)。 * Java 的基本数据类型:int、long、...

    java的静态域实例域

    - 对于不变对象(immutable objects),所有域都是final和静态的,这样可以提高性能并防止意外修改。 总之,理解和熟练运用Java的静态域和实例域以及它们与构造方法的关系是Java程序员的基本技能。通过合理的设计和...

    论C#与Java之异同

    8. **Strings Are Immutable** - **不可变字符串**: 在这两种语言中,字符串对象一旦创建后,其值就不能改变。 9. **Unextendable Classes** - **不可扩展的类**: 两种语言都支持定义不可被继承的类。 10. **...

Global site tag (gtag.js) - Google Analytics