Java不可变类的设计

    xiaoxiao2022-07-13  152

    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<Integer> list = new ArrayList<>(); private final List<Integer> 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<Integer> 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》

    最新回复(0)