一个Java字符串真的是不可变的?

  • 回答 (2)
  • 关注 (0)
  • 查看 (44)

我们都知道String在Java 中是不可变的,但请检查以下代码:

String s1 = "Hello World";  
String s2 = "Hello World";  
String s3 = s1.substring(6);  
System.out.println(s1); // Hello World  
System.out.println(s2); // Hello World  
System.out.println(s3); // World  
Field field = String.class.getDeclaredField("value");  
field.setAccessible(true);  
char[] value = (char[])field.get(s1);  
value[6] = 'J';  
value[7] = 'a';  
value[8] = 'v';  
value[9] = 'a';  
value[10] = '!';  
System.out.println(s1); // Hello Java!  
System.out.println(s2); // Hello Java!  
System.out.println(s3); // World  

为什么这个程序是这样操作的?为什么价值s1和s2变化,但不是s3?

Bilibili科技Bilibili科技提问于
最爱开车啦互联网的敏感者回答于

你正在使用反射来访问字符串对象的“实现细节”。不变性是对象的公共接口的特征。

以往V回答于

你使用反射来规避String的不变性 - 这是一种“攻击”的形式。

有很多你可以创建的例子(例如,你甚至可以实例化一个Void对象),但这并不意味着String不是“不可变的”。

在这种情况下,这种类型的代码可能会被用于您的优势,并且是“良好的编码”,例如在尽可能早的时刻(在GC之前)从内存中清除密码。

根据安全管理器,您可能无法执行您的代码。

扫码关注云+社区

领取腾讯云代金券