This question already has answers here:
Is a Java string really immutable?
(15个答案)
5年前关闭。
Java字符串池加上反射会在Java中产生一些无法想象的结果:
上面的代码将打印:
马里奥怎么了?
...然后您将看到
(15个答案)
5年前关闭。
Java字符串池加上反射会在Java中产生一些无法想象的结果:
import java.lang.reflect.Field;
class MessingWithString {
public static void main (String[] args) {
String str = "Mario";
toLuigi(str);
System.out.println(str + " " + "Mario");
}
public static void toLuigi(String original) {
try {
Field stringValue = String.class.getDeclaredField("value");
stringValue.setAccessible(true);
stringValue.set(original, "Luigi".toCharArray());
} catch (Exception ex) {
// Ignore exceptions
}
}
}
上面的代码将打印:
"Luigi Luigi"
马里奥怎么了?
最佳答案
基本上,您已更改它。是的,通过反射,您可能会违反字符串的不变性……并且由于字符串内部化,这意味着对“Mario”的任何使用(除了在编译时已解决的较大的字符串常量表达式中)都会结束在该程序的其余部分中将其命名为“Luigi”。
这就是为什么反射需要安全权限的原因...
注意,由于str + " " + "Mario"
的左关联性,表达式+
不执行任何编译时串联。实际上是(str + " ") + "Mario"
,这就是为什么您仍然看到Luigi Luigi
的原因。如果将代码更改为:
System.out.println(str + (" " + "Mario"));
...然后您将看到
Luigi Mario
,因为编译器会将" Mario"
插入到了"Mario"
的不同字符串中。10-04 10:16