尝试使用反射修改 String 值时 JVM 崩溃
这是我的第一个问题,希望我不会犯任何可怕的错误。 假设没有 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
病人:医生,医生,我这样做的时候很疼(用锤子敲打手臂)。
医生:那就别这么做了。
你真的不应该试图弄乱字符串的内容。字符串被设计为不可变的。现在我敢说这是一个 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.
它看起来像
"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