不可变类
不可变类的意思是在创建该类的实例后,该实例的实例变量是不可以改变的。Java提java.lang.String类都是不可变类,当创建它们的实例后,实例的实例变量也是不可改变的。
如:
Double d = new Double(2.2);
String str = new String("cuzz");
如果需要创建一个自定义的不可变类,应具备以下几个规则
使用private和final修饰符来修饰该类的成员变量
提供带参数的构造器,用于根据传入参数来初始化类里的成员变量
提供getter方法,不需要setter方法
下面定义一个不可变Adress类,程序把Address类的detail和postCode成员变量都使用private隐藏起来,并使用final修饰这两个成员变量,不允许其他方法修改这两个成员变量的值
public class Address {
private final String detail;
private final String postCode;
// 在构造器里初始化两个实例变量
public Address() {
this.detail = "";
this.postCode = "";
}
public Address(String detail, String postCode) {
this.detail = detail;
this.postCode = postCode;
}
// 仅为两个实例变量提供getter方法
public String getDetail() {
return this.detail;
}
public String getPostCode() {
return this.postCode;
}
// 重新equeal方法
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj != null && obj.getClass() == Address.class) {
Address address = (Address) obj;
// 当detail和postCode同时相等时
if (address.detail == detail && address.postCode == postCode) {
return true;
}
}
return false;
}
public int hashCode() {
return detail.hashCode() + postCode.hashCode() * 31;
}
}
缓存实例的不可变类
不可变类的实例状态不可以改变,可以很方便的被多个对象所共享,如果程序经常需要使用相同的不可变实例,可以考虑缓存这种不可变的实例。
public class CacheImmutable {
private static int MAX_SIZE = 10;
// 使用数组来缓存已有的实例
private static CacheImmutable[] cache = new CacheImmutable[MAX_SIZE];
// 记录缓存实例在缓存的位置 cache[pos-1]是最新的实例
private static int pos = 0;
private final String name;
private CacheImmutable(String name) {
this.name = name;
}
private String getName() {
return 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];
}
}
// 如果缓存池已满
if (pos == MAX_SIZE) {
// 把缓存的第一个对象覆盖 把刚刚生成的对象放在缓存池最开始
pos = 0;
cache[pos++] = new CacheImmutable(name);
}else {
cache[pos++] = new CacheImmutable(name);
}
return cache[pos-1];
}
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj != null && obj.getClass() == CacheImmutable.class) {
CacheImmutable ci = (CacheImmutable) obj;
return name.equals(ci.getName());
}
return false;
}
}
测试类:
public class CacheImmutableTest {
public static void main(String[] args) {
CacheImmutable c1 = CacheImmutable.valueOf("cuzz");
CacheImmutable c2 = CacheImmutable.valueOf("cuzz");
System.out.println(c1 == c2 ); // 输出true
}
}
与Java提供的java.lang.Integer类采用的相同的策略
public class IntegerCacheTest {
public static void main(String[] args) {
// 生成新的Integer对象
Integer in1 = new Integer(6);
// 生成新的Integer对象 并缓存该对象
Integer in2 = Integer.valueOf(6);
// 直接从缓存中取出Integer对象
Integer in3 = Integer.valueOf(6);
System.out.println(in1 == in2); // false
System.out.println(in2 == in3); // true
// 由于Integer只缓存-128~127之间
Integer in4 = Integer.valueOf(200);
Integer in5 = Integer.valueOf(200);
System.out.println(in4 == in5); // false
}
}