我们找到string的jdk源码
1.看到String类被final修饰。这里你就要说出被final修饰的类不能被继承,方法不能被重写,变量不能被修改。
2.看到final修饰的char[]代表了被存储的数据不可更改性。但是:虽然final代表了不可变,但仅仅是引用地址不可变,并不代表了数组本身不会变,请看下面图片
上图说明:数组中的值发生了改变。
上图说明:无论如何修改,数组的地址值不会改变。
综上:所以在这里只有final修饰是不能确保string的不可变性。还需要privite修饰。才能确保不可变性。
除了 String 类,系统类库中还提供了一些其他的不可变类,基本类型的包装类、BigInteger、BigDecimal等等。这些不可变类比可变类更加易于设计、实现和使用,不容易出错且更加安全。另外,要记住并不仅仅是靠一个 final 关键字来实现不可变的,更多的是靠类内部的具体实现细节。
String
的确是个不可变类,但是真的没有办法改变 String 对象的值吗?答案肯定是否定的,反射机制可以做到很多平常做不到的事情。String str = "123"; System.out.println(str); Field field = String.class.getDeclaredField("value"); field.setAccessible(true); char[] value = (char[]) field.get(str); value[1] = ‘3‘;
执行结果:
123
133
很显然,通过反射可以破坏String
的不可变性。
参考:https://blog.csdn.net/weixin_44946052/article/details/89409188
https://www.jianshu.com/p/9c7f5daac283
原文:https://www.cnblogs.com/mukk/p/12263356.html