java 不可变类 缓存实例

来源:互联网 发布:百度云 for mac 编辑:程序博客网 时间:2024/04/30 22:55

不可变类?
是指当创建了这个类的实例后,就不允许修改它的属性值。在JDK的基本类库中,所有基本类型的包装类,如Integer和Long类,都是不可变类,java.lang.String也是不可变类。

如何创建一个不可变类?
1. 所有成员都是private
2. 不提供对成员的改变方法,例如:setXXXX
3. 确保所有的方法不会被重载。手段有两种:使用final Class(强不可变类),或者将所有类方法加上final(弱不可变类)。
4. 如果某一个类成员不是原始变量(primitive)或者不可变类,必须通过在成员初始化(in)或者get方法(out)时通过深度clone方法,来确保类的不可变。
(primitive变量: boolean,byte, char, double ,float, integer, long, short)
下面是一个自定义不可变类的例子:

public final class FinalClass {      private final int[] myArray;        public FinalClass(int[] anArray) {          this.myArray = anArray.clone();       }        public String toString() {          StringBuffer sb = new StringBuffer("Numbers are: ");          for (int i = 0; i < myArray.length; i++) {              sb.append(myArray[i] + " ");          }          return sb.toString();      }  } 

不可变类的用途?
不可变类的实例的状态不会变化,这样的实例可以安全地被其他与之关联的对象共享,还可以安全地被多个线程共享。
为了节省内存空间,优化程序的性能,应该尽可能地重用不可变类的实例,避免重复创建具有相同属性值的不可变类的实例。
下面是一个缓存不可变类实例的例子:

package com.basic.finalclass;import java.lang.ref.SoftReference;import java.util.HashSet;import java.util.Iterator;import java.util.Set;public class BasicFinalClass {public static void main(String argv[]) {FinalClass m1 = FinalClass.valueOf("a");FinalClass m2 = FinalClass.valueOf("b");FinalClass m3 = FinalClass.valueOf("a");System.out.println(m1.toString());System.out.println(m2.toString());System.out.println(m3.toString());System.out.println(m1 == m3);}}@SuppressWarnings("rawtypes")final class FinalClass {private final String type;private final static int[] myArray = new int[]{1,2,3};private final static Set<SoftReference> types = new HashSet<SoftReference>();public FinalClass(String type) {this.type = type;}public String toString() {StringBuffer sb = new StringBuffer("Type are: " + type + " Numbers are: ");for (int i = 0; i < myArray.length; i++) {sb.append(myArray[i] + " ");}sb.append(" myArray are: " + myArray);return sb.toString();}@SuppressWarnings("unchecked")public static FinalClass valueOf(String type) {Iterator<SoftReference> it = types.iterator();while (it.hasNext()) {SoftReference ref = it.next();FinalClass obj = (FinalClass)ref.get();if (type != null && obj.type.equals(type)) {return obj;}}FinalClass obj = new FinalClass(type);types.add(new SoftReference(obj));return obj;}}

总结:
1)为了防止耗尽内存,在实例缓存中存放的是对象的软引用(SoftReference),如果一个对象仅仅持有软引用,Java虚拟机会在内存不足的情况下回收它的内存
2)在程序的生命周期中,对于程序不需要经常访问的实例,应该使用new语句创建它,使它能及时结束生命周期
3)对于程序需要经常访问的实例,那就用valueOf()方法来获得它,因为该方法能把实例放到缓存中,使它可以被重用
4)只有满足以下条件的不可变类才需要实例缓存
A、不可变类的实例的数量有限

B、在程序运行过程中,需要频繁访问不可变类的一些特定实例。这些实例拥有与程序本身同样长的生命周期

参考:

http://soft.chinabyte.com/database/285/11363785.shtml

0 0
原创粉丝点击