Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

effect of changing String using reflection

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).

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

p.s. String is just an example, I am interested actually in a general answer, in addition to the example.

thanks!

like image 598
amit Avatar asked Aug 03 '11 20:08

amit


2 Answers

After compilation some strings may refer to the one instance, so, you will edit more than you want and never know what else are you editing.

public static void main(String args[]) throws Exception {
    String s1 = "Hello"; // I want to edit it
    String s2 = "Hello"; // It may be anywhere and must not be edited
    Field f = String.class.getDeclaredField("value");
    f.setAccessible(true);
    f.set(s1, "Doesn't say hello".toCharArray());
    System.out.println(s2);
}

Output:

Doesn't say hello
like image 55
Sergey Fedorov Avatar answered Sep 28 '22 12:09

Sergey Fedorov


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:

  • 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 like function("Bob"); in this scenario the string "Bob" is changed throughout your app (this will also be true of string constants declared as final).
  • 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.

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.

like image 30
Dan Tao Avatar answered Sep 28 '22 11:09

Dan Tao