尝试使用反射修改 String 值时 JVM 崩溃

发布于 2024-10-06 04:24:59 字数 962 浏览 3 评论 0原文

这是我的第一个问题,希望我不会犯任何可怕的错误。 假设没有 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 崩溃...

谢谢

This is my first question I hopefully don't make any terrible mistake.
Assuming no SecurityManager is preventing me from doing this :

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) {}
    }
}

If the size of the string is 1 (the example above) the JVM crash (the crash dump shows an EXCEPTION_ACCESS_VIOLATION error) however if the size of the string is greater than 1 this code snippet works for me.

Note: I assume that the appropiate use for setting a field's value via reflection is using valueField.set(obj, value) Field method but I want to know why the JVM crash...

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小猫一只 2024-10-13 04:24:59

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

医生:那就别这么做了。

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

Patient: Doctor, doctor, it hurts when I do this (bangs arm with hammer).

Doctor: Don't do that then.

You really shouldn't be trying to mess with the contents of a string. Strings are designed to be immutable. Now I dare say it's a JVM bug that it crashes so dramatically (it doesn't on my box, btw - it would be useful if you'd tell us which operating system and JVM version you're using) but the simple answer is not to try to go behind the system's back.

时光礼记 2024-10-13 04:24:59

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

it looks like that array of chars for "1" and a number of other interned Strings (like "true", "false", "root", "class", etc) cannot be changed in Windows JVM. I.e. you cannot assign new values to array elements. But you can assign new array for that String object. Example

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文