【Java】不可变类(immutable)总结

1、不可变类
(1)不可变类是指这个类的实例一旦创建完成后,就不能改变其成员变量值,也就是不能改变对象的状态。
(2)Java 中八个基本类型的包装类和 String 类都属于不可变类,而其他的大多数类都属于可变类。
(3)不可变对象是线程安全的。
2、如何设计不可变类?
(1)类声明为final,不可以被继承。
(2)所有成员变量定义为私有和final(private final)。
(3)不提供改变成员变量的方法。
(4)通过构造器初始化成员,若构造器传入引用数据类型需要进行深拷贝。

public final class ImmutableDemo {  
    private final int[] myArray;  
    public ImmutableDemo(int[] array) {  
        this.myArray = array; // wrong  
    }  
}

这种方式不能保证不可变性,myArray和array指向同一块内存地址,用户可以在ImmutableDemo之外通过修改array对象的值来改变myArray内部的值。为了保证内部的值不被修改,可以采用深度copy来创建一个新内存保存传入的值。
正确方式如下:

public final class MyImmutableDemo {  
    private final int[] myArray;  
    public MyImmutableDemo(int[] array) {  
        this.myArray = array.clone(); // right 
    }   
}

(5)在getter方法中不能返回对象本身,而是返回对象的拷贝。
3、看看String类源码是如何构造不可变性的

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence
{
    /** The value is used for character storage. */
    private final char value[];//0.private final
    ....
    public String(char value[]) {//1.构造器深拷贝
        this.value = Arrays.copyOf(value, value.length);
    }
    ...
    public char[] toCharArray() {
        // Cannot use Arrays.copyOf because of class initialization order issues
        char result[] = new char[value.length];
        System.arraycopy(value, 0, result, 0, value.length);//2.返回对象拷贝
        return result;
    }
    ...
}

4、String对象的不可变性的优点
(1)线程安全。
(2)字符串常量池的需要。
只有当字符串是不可变的,字符串池才有可能实现。字符串常量池可以将一些字符常量放在常量池中重复使用,避免每次都重新创建相同的对象、节省存储空间。
(3)字符串很适合作为Map中的key。
5、String对象的是否真的不可变
虽然String对象将value设置为final,并且还通过各种机制保证其成员变量不可改变。但是还是可以通过反射机制的手段改变其值。

参考文档:
https://www.cnblogs.com/jaylon/p/5721571.html

 

 

 

  • 7
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值