Java中的String类真的不可变吗?这段代码却违反了定律

我们都知道 Java 中的 String 类的设计是不可变的,因为String类是用final关键字修饰,这就表示String不可继承,而且String类的主力成员字段value是个char[]数组,也是用final修饰的,而final修饰的字段一经创建后就不可改变。这就是String类的设计不可变的原因。

来看下 String 类的源码。

如果有想要学习Java的程序员,可来我们的java技术学习扣qun哦:86327,0610里面免费送java的视频教程噢!小编也是一名从事了6年java开发的全栈工程师,花了近一个月整理了一份较适合18年学习的java干货,加群即可领取,都是免费的哦,送给每一位java小伙伴,欢迎初学和进阶中的小伙伴。

可以看出 String 类是 确实是final 类型的,不能被继承。而其 value也就是对字符数组的封装,即 char[],其值被定义成私有制的final ,也就是说不能被外界修改,就是不可变。

然而,String 真的 "不可变 " 吗?来看看下面这段代码

看到这里你可能会问:str 不是由 Python 变成 Java 了吗?然后通过 substring 方法变成 Java 了吗?

在初学者中,这是比较广泛的一个误区,因为从上面看 String 的结构,就可以得知字符串其实是有字符数组构成的,而其中的str 只是起了一个引用作用罢了,当中第一次引用了 "Python"之后才变成了 "Java",而 substring 也是用 Arrays.copyOfRange 方法重新复制字符数组构造了一个新的字符串。

可以看到,这里的字符串并不是不可变的,知识变更了字符串的引用而已。而从这一角度入手,似乎能够设计出一段违背这个定律的代码!

这段代码中通过反射,直接就改变底层字符数组的值,这就实现了字符串的“不可变”性。然而在实际过程中,这种的一般不建议使用,因为这已经违反了Java对于String类定义的不可变的设计原则,很容易Bug的。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180919A1PLWS00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券