什么是 Java 中的不可变类?

不可变类是指创建后无法修改对象状态的类。String 类是Java中典型的不可变类。

1. 不可变类的特点

  • 一旦创建,对象的状态就不能被改变。
  • 所有成员变量都是 final 类型。
  • 所有可变成员变量都是私有的,并且没有提供修改它们的公共方法。

2. 不可变类的示例

String 类为例,执行 s += "a"; 实际上是创建了一个新的 String 对象,而原始对象保持不变。

因为无法被修改,所以像执行s += "a";这样的方法,其实返回的是一个新建的String对象,老的s指向的对象不会发生变化,只是s的引用指向了新的对象而已。

3. 不可变类的优点

  • 安全性:由于对象状态不可变,可以在多线程环境中安全使用而无需同步。
  • 简单性:简化了编程模型,因为不需要考虑对象状态的变化。

4. 性能考虑

  • 在字符串拼接频繁的场景下,应避免使用 + 操作符,因为这会导致频繁创建新对象。
  • 可以使用 StringBuilderStringBuffer 来优化性能。

5. 如何实现一个不可变类?

  • 使用 final 修饰类:防止继承。
  • 使用 final 修饰所有成员变量:确保引用不可变。
  • 使成员变量私有:隐藏类的内部状态。
  • 不提供修改成员变量的公共方法:防止外部修改。

示例代码

public final class ImmutableClass {
    // String 本质是一个char 数组,然后用 final修饰,不过 final限制不了数组内部的数据,所以这还不够。
    //所以value 是用private修饰的,并且没有暴露出set方法,这样外部其实就接触不到value所以无法修改。
    private final int value;

    public ImmutableClass(int value) {
        this.value = value;
    }

    // 不提供任何修改value的方法
    
    //当然还是有修改的需求,比如replace方法,所以这时候就需要返回一个新对象来作为结果。
     public String replace(char oldChar, char newChar) {
        if (oldChar != newChar) {
            int len = value.length;
            int i = -1;
            char[] val = value; /* 避免使用 getfield 指令 */
            while (++i < len) {
                if (val[i] == oldChar) {
                    break;
                }
            }
            if (i < len) { // 如果找到了 oldChar
                char[] buf = new char[len];
                for (int x = 0; x < i; x++) {
                    buf[x] = val[x];
                }
                while (i < len) {
                    char c = val[i];
                    buf[i] = (c == oldChar) ? newChar : c;
                    i++;
                }
                return new String(buf, share: true); // share 参数在实际代码中不存在,这里假设为简化说明
            } else {
                return this; // 如果没有找到 oldChar,返回原字符串
            }
        } else {
            return this; // 如果 oldChar 和 newChar 相同,直接返回原字符串
        }
    }
}

总结一下就是私有化变量,然后不要暴露set方法,即使有修改的需求也是返回一个新对象。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值