这是对 java 中字符串不变性的妥协吗?
Is this compromise to string immutablity in java?
我们都知道字符串在 java 中是不可变的 - 一旦创建了字符串,内容就无法更改。
String使用字符数组char[] value
存储字符串内容,这里是java代码-
/** The value is used for character storage. */
private final char value[];
如果我们访问字段 values[]
并更改它会怎样?请参阅此代码 -
String name = "Harish";
System.out.println(name); // Harish
Field field = name.getClass().getDeclaredField("value");
field.setAccessible(true);
char[] value = (char[]) field.get(name);
value[0] = 'G';
value[1] = 'i';
System.out.println(Arrays.toString(value)); // [G, i, r, i, s, h]
System.out.println(name); // Girish
这样,我认为,我们可以改变字符串的内容,这违反了字符串不变性原则。
我是不是漏了什么?
不,你没有遗漏任何东西。当您使用反射并使不可访问的字段可访问时,您明确要求失去以 "normal" OOP 方式使用该类型时提供的所有保证。
我们都知道字符串在 java 中是不可变的 - 一旦创建了字符串,内容就无法更改。
String使用字符数组char[] value
存储字符串内容,这里是java代码-
/** The value is used for character storage. */
private final char value[];
如果我们访问字段 values[]
并更改它会怎样?请参阅此代码 -
String name = "Harish";
System.out.println(name); // Harish
Field field = name.getClass().getDeclaredField("value");
field.setAccessible(true);
char[] value = (char[]) field.get(name);
value[0] = 'G';
value[1] = 'i';
System.out.println(Arrays.toString(value)); // [G, i, r, i, s, h]
System.out.println(name); // Girish
这样,我认为,我们可以改变字符串的内容,这违反了字符串不变性原则。
我是不是漏了什么?
不,你没有遗漏任何东西。当您使用反射并使不可访问的字段可访问时,您明确要求失去以 "normal" OOP 方式使用该类型时提供的所有保证。