immutable不可变类

Immutable不可变类

什么是不可变类

​ 一个类的对象在通过构造方法创建后,如果状态不会再被改变,那么它就是一个不可变(immutable)类。它的所有成员变量的赋值仅在构造方法中完成,不会提供任何setter方法提供外部类去修改

​ 在程序中通常会启用多线程,但是这会造成一些无法预料的问题,所以为了保护状态的原子性、可见性、有序性。我们会常常使用Synchronized(同步)来进行解决

​ 假如说类是不可变的,那么对象的状态也就是不街边的,这样的话,每次修改对象的状态,就会产生一个新的对象供不同的线程使用,这样也就不会担心并发问题。

常见的不可变类

​ 我们最熟悉的不可变类,当然是String类,那么为啥String被设计为不可变的呢。

  • 常量池的需要

    • 字符串常量池是Java堆内存中一个特殊的存储区域,这样可以减少JVM的内存开销,提高效率
  • hashCode的需要

    • 因为字符串的不可变性,所以在它创建的时候,其hashCode就被缓存了,因此非常适合做哈希值(比如HshMap的键),多次调用只返回同一个值,来提高效率
  • 线程安全

    • 如果对象的状态是可变的,那么在多线程环境下,就很容易造成不可预期的结果。而String是不可变的,就可以在多个线程之间共享,不需要同步处理

    除了String类这个常见的不可变类外,包装器类Integer、Long等也是不可变类

自定义不可变类

不可变类创建的条件:

  • 确保类是final的,不允许被其他类继承
  • 确保所有的成员变量(字段)是final的,这样它们就只能在构造方法中初始化值,并且不会在随后被修改
  • 不要提供任何setter方法
  • 如果要修改类的状态,必须返回一个新的对象

基于此要是一个不可变类中包含了可变类的对象,那么就需要确保返回的是可变对象副本,即需要修改其get方法

public people getName(){
    
    
    Name clone = new Name();
    clone.setPName(this.name.getPName());
    clone.setSName(this.name.getSName());
    return clone;
}

​ 这样的话,构造方法初始化后的Book对象就不会再被修改了。

总结

​ 不可变类有很多优点,尤其是在多线程环境下,它非常安全。尽管每次修改都会创建一个新的对象,增加了内存的消耗,但是这个缺点还是可以接受的。

猜你喜欢

转载自blog.csdn.net/issunmingzhi/article/details/107632125