This question already has answers here:
Is a Java string really immutable?

(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