Java不可变类的设计

1.1 不可变类

    不可变类是指其实例创建后状态不能被修改的类。它们的实例信息是由调用构造函数时就提供,不会提供对外的设值方法,保证它们的状态不会被改变。

 

1.1.1 不可变类的好处

    在Java平台类库中包含许多不可变的类,如String、基本类型的包装类以及Collections工具类中Unmodifiable对应各种集合的实现。不可变类比可变类更加易于设计、实现和使用,不容易出错,且更加安全。

  • 不可变对象很简单,因为只有一种状态(创建时的状态)
  • 不可变对象可以被自由的共享
  • 不可变对象一定是线程安全的,它们不需要额外的同步......

 

1.1.2 不可变类的设计规则

  • 不提供对外修改对象状态的设值方法
  • 声明的所有域都是final类型^
  • 保证类不会被扩展,正确的被创建

需要注意:并不是所有的域都必须声明为final类型,具体可参考String类中的hash字段;即使对象中的所有的域都是final类型的,也不能保证对象是不可变的,因为在final类型的域中可能指向的是可变对象。

 

1.1.3 不可变类的具体设计

public class ImmutableClass {
	
	private final int x;
	private final int y;
	
	private int hash; // 缓存hashcode,内部计算可能发生改变但是不会对外提供
    
        // final域指向的是可变对象,不能返回该对象引用(或者使用深拷贝) ❌
	// private final List list = new ArrayList<>();
        private final List list = Collections.unmodifiableList(Arrays.asList(1,2));
	
	/*
	 * 缓存对象
	 */
	public static final ImmutableClass ZERO_ONE = new ImmutableClass(0, 1);
	public static final ImmutableClass ONE_TWO = new ImmutableClass(1, 2);
	
	// 使用 静态工厂方法+私有构造器 使类变成final
	private ImmutableClass(int x, int y) {
		this.x = x;
		this.y = y;
	}
	public static ImmutableClass valueOf(int x, int y) {
		return new ImmutableClass(x, y);
	}
	 
	public ImmutableClass plus(ImmutableClass u) {
		return new ImmutableClass(x + u.x, y + u.y);
	}
	
	public ImmutableClass minus(ImmutableClass u) {
		return new ImmutableClass(x - u.x, y - u.y);
	}
	
	//....
	
	public int getX() {
		return x;
	}
	public int getY() {
		return y;
	}
	public List getList() {
		return list;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj == this)
			return true;
		if (!(obj instanceof ImmutableClass))
			return false;
		ImmutableClass u = (ImmutableClass)obj;
		return Integer.compare(u.x, x) == 0
			&& Integer.compare(u.y, y) == 0;
	}
	
	@Override
	public int hashCode() {
		int result = hash;
		if (result == 0) {
			result = Objects.hash(x,y);
			hash = result;			
		}
		return result;
	}
	
}

 

总结

      如果某个对象在被创建后其状态不能被修改,那么这个对象就称为不可变对象。不可变类唯一的缺点就是:对于每个不同的值都需要去创建一个新对象。 

参考书籍:《Effective Java》

你可能感兴趣的:(Java并发编程)