使用反射改变字符串的效果
众所周知,String 在 java 中是不可变的.但是,可以通过获取字段并设置访问级别来使用反射来更改它.(我知道这是不明智的,我不打算这样做,这个问题是纯理论的).
As we all know, String is immutable in java. however, one can change it using reflection, by getting the Field and setting access level. (I know it is unadvised, I am not planning to do so, this question is pure theoretical).
我的问题:假设我知道自己在做什么(并根据需要修改所有字段),程序会正常运行吗?或者 jvm 是否进行了一些依赖于 String 不可变的优化?我会遭受性能损失吗?如果是这样,它做了什么假设?程序会出什么问题
my question: assuming I know what I am doing (and modify all fields as needed), will the program run properly? or does the jvm makes some optimizations that rely on String being immutable? will I suffer performance loss? if so, what assumption does it make? what will go wrong in the program
附言String 只是一个示例,除了示例之外,我实际上对一般答案感兴趣.
p.s. String is just an example, I am interested actually in a general answer, in addition to the example.
谢谢!
推荐答案
你这样做肯定是自找麻烦.这是否意味着您肯定会立即看到错误?不.在很多情况下,您可能会侥幸逃脱,这取决于您在做什么.
You are definitely asking for trouble if you do this. Does that mean you will definitely see bugs right away? No. You might get away with it in a lot of cases, depending on what you're doing.
这里有几种情况会咬你:
Here are a couple of cases where it would bite you:
- 您修改了一个字符串,该字符串恰好在代码中的某处被声明为字面量.例如,您有一个
function
并且在某处它被称为function("Bob")
;在这种情况下,字符串"Bob"
会在整个应用程序中 更改(对于声明为final<的字符串 constants 也是如此/code>).
- 您修改了在子字符串操作中使用的字符串,或者是子字符串操作的结果.在 Java 中,获取字符串的子字符串实际上使用与源字符串相同的底层字符数组,这意味着对源字符串的修改会影响子字符串(反之亦然).
- 您修改了一个字符串,该字符串恰好被用作地图某处的键.它将不再与原始值进行比较,因此查找将失败.
- You modify a string that happens to have been declared as literal somewhere within the code. For example you have a
function
and somewhere it is being called likefunction("Bob")
; in this scenario the string"Bob"
is changed throughout your app (this will also be true of string constants declared asfinal
). - You modify a string which is used in substring operations, or which is the result of a substring operation. In Java, taking a substring of a string actually uses the same underlying character array as the source string, which means modifications to the source string will affect substrings (and vice versa).
- You modify a string that happens to be used as a key in a map somewhere. It will no longer compare equal to its original value, so lookups will fail.
我知道这个问题是关于 Java 的,但我 写了一个不久前的博文 说明了如果您在 .NET 中对字符串进行变异,您的程序可能会表现得多么疯狂.情况真的很相似.
I know this question is about Java, but I wrote a blog post a while back illustrating just how insane your program may behave if you mutate a string in .NET. The situations are really quite similar.
相关文章