一、不可变类的实例状态不可改变,能够被多个对象很方便的共享java
二、若是程序常常使用某个不可变类的实例,那么把该实例保存近缓存是一个好的选择,不用每次都生成新的实例对象,消耗系统开销数组
以下代码实例:将建立的不可变类实例进行缓存缓存
import static java.lang.System.*; import java.util.Arrays; class CacheImmutable{ //-定义缓存数组的长度,私有的,静态的,不可更改的 private static final int MAX_SIZE=3; //-定义缓存数组,来缓存已有的实例,静态的,不可更改的,不变类的要素之一 private static final CacheImmutable[] cache = new CacheImmutable[MAX_SIZE]; //-记录缓存实例在缓存中的位置,cache[pos-1]是最新缓存进来的实例 private static int pos=0; //-记录当前实例的name,不可更改的,每一个实例的name都不一样,因此不能是static修饰 private final String name; //-获取当前实例的name,只设置获取getter方法,不设置设置setter方法,不变类的要素之一 public String getName(){ return this.name; } //-带参数的构造器,name赋值的惟一路径,private修饰,不能外部new新的实例,不变类的要素之一 private CacheImmutable(String name){ this.name=name; } //-获取类实例对象的惟一方式 public static CacheImmutable valueOf(String name){ //-循环缓存数组,判断新定义的实例对象是否已经存在,如存在,直接返回已有的实例,再也不存入新的实例 for(int i=0;i<MAX_SIZE;i++){ if(cache[i]!=null&&cache[i].getName().equals(name)){ return cache[i]; } } //-若是缓存数组已经存满,新的实例覆盖第一个旧实例,并把位置标为 1,若是缓存没满,保存进缓存,位标+1,并返回该实例 if(pos==MAX_SIZE){ cache[0] = new CacheImmutable(name); pos=1; }else{ cache[pos++] = new CacheImmutable(name); } return cache[pos-1]; } //-重写Object类的equals()方法 public boolean equals(Object obj){ if(this==obj){ return true; } if(obj!=null&&obj.getClass()==CacheImmutable.class){ CacheImmutable ci = (CacheImmutable)obj; if(this.getName().equals(ci.getName())){ return true; } } return false; } //-重写Object类的hashCode()方法 public int hashCode(){ return name.hashCode(); } //-获取当前实例在缓存中是第几个 public int getPos(){ return pos; } //-获取整个缓存数组 public CacheImmutable[] getArray(){ return cache; } } public class CacheImmutableTest{ public static void main(String[] args){ //-定义一个 CacheImmutable类实例:cache1,name为:ImmutableClass,并保存进缓存 CacheImmutable cache1 = CacheImmutable.valueOf("ImmutableClass"); //-输出当前实例在缓存中的位置 out.println(cache1.getPos()); //-遍历整个缓存,输出缓存中每一个实例的name值 for(int i=0;i<cache1.getPos();i++){ out.println(cache1.getArray()[i].getName()); } //-输出整个缓存数组 out.println(Arrays.toString(cache1.getArray())); out.println(); //-新定义的实例:cache2 与 已经保存进缓存的实例:cache1的name值相等,因此视为已存在实例,不会再次进缓存 CacheImmutable cache2 = CacheImmutable.valueOf("ImmutableClass"); out.println(cache2.getPos()); for(int i=0;i<cache2.getPos();i++){ out.println(cache2.getArray()[i].getName()); } out.println(Arrays.toString(cache2.getArray())); out.println(); CacheImmutable cache3 = CacheImmutable.valueOf("ImmutableClass_a"); out.println(cache3.getPos()); for(int i=0;i<cache3.getPos();i++){ out.println(cache3.getArray()[i].getName()); } out.println(Arrays.toString(cache3.getArray())); out.println(); CacheImmutable cache4 = CacheImmutable.valueOf("ImmutableClass_b"); out.println(cache4.getPos()); for(int i=0;i<cache4.getPos();i++){ out.println(cache4.getArray()[i].getName()); } out.println(Arrays.toString(cache4.getArray())); out.println(); out.println(cache1.equals(cache2)); out.println(cache1.equals(cache3)); out.println(); //-新定义的实例:cache5,会覆盖缓存数组中的第一个实例(由于缓存已满), CacheImmutable cache5 = CacheImmutable.valueOf("ImmutableClass_c"); out.println(cache5.getPos()); for(int i=0;i<cache5.getPos();i++){ out.println(cache5.getArray()[i].getName()); } out.println(Arrays.toString(cache5.getArray())); } }
运行效果:性能
总结:this
一、是否须要隐藏类的构造器,彻底取决于系统需求对象
二、盲目乱用缓存可能致使系统性能降低blog
三、缓存的对象会占用内存,若是对象只用一次,重复使用的几率不大,缓存该实例就弊大于利内存
四、若是某个对象须要频繁的调用,缓存该实例就利大于弊ci
Java提供的Integer类,就采用了上面CacheImmutable类相同的缓存策略:get
一、若是采用 new 构造器来建立 Integer 对象,返回的是全新的 Integer 对象
二、若是采用 valueOf() 方法来建立 Integer 对象,则在建立该对象的同时,会缓存该方法建立的对象
三、Integer 只缓存 -128-127之间的 Integer 对象,超过该范围的对象不会缓存
以下代码示例:
public class IntegerCache{ public static void main(String[] args){ //-生成新的Integer对象实例:a Integer a = new Integer(5); //-生成新的Integer对象实例:b,并缓存 Integer b = Integer.valueOf(5); //-直接从缓存里获取对象,由于缓存里相同对象已经存在 Integer c = Integer.valueOf(5); //-false System.out.println(a==b); //-true System.out.println(b==c); //-Integer只缓存-128-127之间的值,200对应的Integer对象没有被缓存 Integer d = Integer.valueOf(200); Integer e = Integer.valueOf(200); //-由于没缓存,因此是两个不一样的对象,返回false System.out.println(d==e); } }
运行结果: