8 Replies Latest reply: May 25, 2011 3:01 PM by 864482 RSS

    Hacking immutability with reflection and its implications

      Hi all,

      When I was experimenting with Java reflection, I came to a situation where-in I could access private and final fields of a class and change its value. So I tried it with Java's most famous immutable object-String. I could change the value stored by the string, still retaining its hashCode() value unchanged, and equals() method not recognizing the change. Following is my test code.
      import java.lang.reflect.Field;
      public class AccessibilityTest {
            * @param args
           public static void main(String[] args) {
                String s = "Joby";
                System.out.println("INITIAL Value (Before change) ");
                Class class1 = String.class;
                try {              
                    Field field = class1.getDeclaredField("value");
                    Object o = field.get(s);
                    if (o instanceof char[]){
                         char[] arr = (char[])o;
                         //Change the internal value of the String.
                         for (int n =0;n<arr.length;n++){
                              arr[n] = 'm';
                } catch (NoSuchFieldException e) {
                    System.out.println("FieldNotFound: " + e);
                } catch (IllegalAccessException e) {
                    System.out.println("Ilegal Access: " + e);
                System.out.println("Value (After change) ");
                System.out.println("\n ----Equality check--- ");
                System.out.println(s+" == Joby ? "+ s.equals("Joby"));
      The interesting output is given below:
      INITIAL Value (Before change) 
      Value (After change) 
       ----Equality check--- 
      mmmm == Joby ? true
      Can some one help me in understanding:

      1) Why this is allowed in Java?
      2) What is the implication of this?

      Thanks in advance,