不可变类


1、什么是不可变类(immutable class)?
    不可变类,顾名思义就是说类的实例是不可被修改的。实例的信息是在创建的时候提供,并且在整个生命周期中都不可改变。 


2、有哪些常见的不可变类?
    Java的String类和所有基本类型的包装类。

3、什么时候需要将类设计为不可变类?
    尽量将一些比较小的对象设计为不可变类(如PhoneNumber和Complex),或者想设计一种有结构的常量的时候,可以考虑设计出一个immutable的类。

4、如何设计不可变类? 
a)将成员变量设置为private final:将成员变量设置为final可以很清晰的表明对象状态不可变的意图。
b)不要提供任何会修改对象状态的方法:将成员设置为final后,这个方法明显多余。
c)保证类不会被拓展:这是为了防止子类对该类方法任意的重写,有两种方式来实现:
  i:将类设置为final;
  ii:将构造方法定义为private,同时提供静态工厂方法;
  我们允许利用组合而不是继承的方式来对类进行拓展。
d)如果类包含指向可变类的引用,则get方法返回该引用指向类的一个拷贝。
package immutable;  
public class Immutable {  
    private final int a;  
    private final ClassA ca;  
   private Immutable(int a, ClassA ca) {
       this.a = a;
       this.ca  = ca;

   }

    public static Immutable getImmutable(int a, ClassA oa){  
        return new Immutable(a, oa);  
    }  
    public ClassA getOA(){  
        return oa.clone();  
    }  
    public int getA() {  
        return a;  
    }  
}   


5、不可变类的优点
    因为immutable类比mutable类更加容易设计,实现和使用。而且不易出错,更加安全。 
       简单:因为对象一旦生成就他的值就固定了,不变了。从对象状态角度上看,它只有一种状态,没有什么状态变化和迁移。相反,对于一个可以变对象,他的状态变化可就多了,你需要有个状态迁移图才能描述清楚他可能的变化,也就是说他的状态空间可能很大。 
       线程安全:因为没有修改方法,所以你不用考虑同步的问题,在并发环境中也可以放心的并发read。 
       节省内存:既然不变对象可以自由的共享。你可以让使用者尽量使用已经存在的实例,而不要重复的创建。你可以定义这些类的一些静态的final实例属性,就像定义一个常量一样。当然你也可以为Immutable 类提供一个静态工厂,由工厂来保证不会创建重复的对象实例。 
    这样也就节省了内存消耗和垃圾回收负担。如果你有这样的对象,在系统中会被大量的,频繁的,并发的读。不放考虑这种模式。其实String就是一个很好的例子。  
    很好的构建基石:你应该比较常用到Set和Map,尤其是map的key值,你是否经常需要考虑这些值会不会在你不经意间变了呢?从而使得影响你设定这个set或map的本意。如果用Immutable对象你就不用担心了吧?这样是为什么你总喜欢用String做key值。当然你也可能想尽量避免重写equals和hashCode方法。 


6、不可变类的缺点

    凡是必然是有利有弊。你知道immutable的对象会因为值的不同而生产新的对象,所以你要谨慎设计你的对象和使用方法。比如String,当你在循环里面连接字符串的时候就不建议你用String的+号,而是用StringBuilder,StringBuilder类用来表示内容可变的字符串,并提供了修改底层字符串的方法。当我们进行字符拼接时,请使用StringBuilder类而非String类,因为前者将比后者快上百倍。这也许也可以知道我们平衡我自己的设计。没准你也可以设计一个immutable类的伙伴(companion)类。 

7、总结

    如果类不能被做成是不可变的,仍然应该尽可能的限制它的可变性。通过降低对象可以存在的状态数,可以更容易的分析该对象的行为,同时降低出错的可能性。


    三种final的使用:
       a)在方法的参数中:如果能加,则推荐加;

       b)在方法前:出于设计的原因,我们不允许子类对该方法进行重写;

       c)在类前:出于安全或者该类不应该具有子类。final class的方法全为final,但属性却没有。

转载地址:http://www.iteye.com/topic/923644

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值