final关键字---不可变类

来源:互联网 发布:mfc 编程 pdf 编辑:程序博客网 时间:2024/05/06 22:23

       不可变类:即该类在创建之后其实例变量是不可变的(immutable).

       其中有两种特殊情况:

     1.不可变类包含的引用类型成员变量是可变类的 

     2.如果系统需要反复使用相同的不可变类的实例,如果反复创建相同的对象会增加系统的开销,此时考虑使用缓存。

      下面代码详细介绍并演示了这两种情况:

1.当不可变类包含的引用类型成员变量是可变类的时候,可能造成创建不可变类失败,因此必须保护好可变的引用类型成员变量.

//name类,这是一个可变类public class Name{private String first;private String last;public Name(String first,String last){this.first=first;this.last=last;}public void setFirst(String first){this.first=first;}public void setLast(String last){this.last=last;}public String getFirst(){return first;}public String getLast(){return last;}//重写toString方法public String toString(){return last+" "+first;}}

//失败的不可变类:当不可变类包含的引用类型成员变量是可变类的时候,可能造成创建不可变类失败public class MutablePerson{private final Name name;public MutablePerson(Name name){this.name=name;}public Name getName(){return name;}}

/*不可变的Person类:当不可变类包含的引用类型成员变量是可变类的时候,可能造成创建不可变类失败,因此必须保护好可变的引用类型成员变量.*/public class ImmutablePerson{private final Name name;public ImmutablePerson(Name name){this.name=new Name(name.getLast(),name.getFirst());}public Name getName(){return new Name(name.getLast(),name.getFirst());}}

//测试类public class ImmutableTest{public static void main(String[] args){//Name对象Name name=new Name("悟空","孙");MutablePerson mp=new MutablePerson(name);System.out.println("可变类:"+mp.getName());name.setFirst("八戒");System.out.println("可变类:"+mp.getName());ImmutablePerson ip=new ImmutablePerson(name);System.out.println(ip.getName());name.setFirst("悟净");System.out.println(ip.getName());System.out.println("可变类:"+mp.getName());System.out.println(ip.getName());}}


 2.缓存实例的不可变类:

        如果系统需要反复使用相同的不可变类的实例,如果反复创建相同的对象会增加系统的开销,此时考虑使用缓存。
 
        Java的Integer类就是利用了缓存机制。
        在这篇文章中有详细的介绍:http://blog.csdn.net/sinat_26342009/article/details/44993539
    

      下面利用数组实现一个缓存实例的不可变类:

     

class CacheImmutableDemo{//定义缓存实例的数组private static final int MAX_SIZE=5;  //最多缓存5个实例private static CacheImmutableDemo[] cache=new CacheImmutableDemo[MAX_SIZE];//记录缓存实例在缓存中的位置,cache[pos-1]是最新缓存的实例private static int pos=0;private final String name;//私有构造器private CacheImmutableDemo(String name){this.name=name;}public String getName(){return name;}public static CacheImmutableDemo valueOf(String name){//遍历已缓存的实例for(int i=0;i<MAX_SIZE;i++){//如果该实例在数组中存在if(cache[i]!=null&&cache[i].getName().equals(name)){//则返回已存在的实例return cache[i];}}//如果缓存池已满,则if(pos==MAX_SIZE){//把缓存池的第一个对象覆盖cache[0]=new CacheImmutableDemo(name);//把pos设为1pos=1;}//如果缓存池未满else{//把新创建的对象缓存起来,pos+1cache[pos++]=new CacheImmutableDemo(name);}return cache[pos-1];}//重写此类的equals和hashCode方法public boolean equals(Object obj){if(this==obj){return true;}if(obj!=null&&obj.getClass()==CacheImmutableDemo.class){CacheImmutableDemo ca=(CacheImmutableDemo)obj;return name.equals(ca.getName());}return false;}public int hashCode(){return name.hashCode();}}

下面是测试类

//测试类public class CacheImmutableTest{public static void main(String[] args){CacheImmutableDemo c1=CacheImmutableDemo.valueOf("test");CacheImmutableDemo c2=CacheImmutableDemo.valueOf("test");CacheImmutableDemo c3=CacheImmutableDemo.valueOf("test");CacheImmutableDemo c4=CacheImmutableDemo.valueOf("test");CacheImmutableDemo c5=CacheImmutableDemo.valueOf("test");System.out.println(c1==c5);}}



0 0