2

这是我的第一个问题,希望不要犯任何可怕的错误。假设没有 SecurityManager 阻止我这样做:

public static void main(String[] args) {
    String str = "1";
    System.out.println("str value before invoke fillStringValueWithX method: " + str);
    fillStringValueWithX(str);
    System.out.println("str value before invoke fillStringValueWithX method: " + str);
}

private static void fillStringValueWithX(String str) {
    if (str != null) {
        try {
        Field fieldValue = String.class.getDeclaredField("value");
        fieldValue.setAccessible(true);
        char[] charValue = (char[]) fieldValue.get(str);
        Arrays.fill(charValue, 'x');
        fieldValue.setAccessible(false);
        } catch (Exception e) {}
    }
}

如果字符串的大小为 1(上面的示例),则 JVM 崩溃(崩溃转储显示 EXCEPTION_ACCESS_VIOLATION 错误)但是如果字符串的大小大于 1,则此代码片段对我有用。

注意: 我假设通过反射设置字段值的适当用途是使用valueField.set(obj, value)Field 方法,但我想知道为什么 JVM 崩溃......

谢谢

4

2 回答 2

3

病人:医生,医生,我这样做的时候很痛(用锤子敲打手臂)。

医生:那就别这样了。

你真的应该试图弄乱字符串的内容。字符串被设计为不可变的。现在我敢说这是一个 JVM 错误,它崩溃得如此剧烈(它不在我的盒子上,顺便说一句 - 如果你告诉我们你正在使用哪个操作系统和 JVM 版本会很有用)但简单的答案是不要试图背着系统走。

于 2010-12-06T19:18:24.213 回答
0

看起来在 Windows JVM 中无法更改用于"1"和许多其他内部字符串(如"true""false""root"、等)的字符数组。"class"即您不能为数组元素分配新值。但是您可以为该 String 对象分配新数组。例子

于 2012-01-04T16:07:15.470 回答