Is String immutable? Yes it is! Really want to change? Ok~
We all know that String is an immutable object, that is, once it is created, its state cannot be changed. In this regard, let's analyze a wave.
Carefully enter the String inside, we can see that it is a final class, then no one can inherit it, very good, very dink.
Then look directly at its soul, a char array, which is also final, so we know how it is immutable.
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { /** The value is used for character storage. */ private final char value[]; /** Cache the hash code for the string */ private int hash;//Default to 0 /** use serialVersionUID from JDK 1.0.2 for interoperability */ private static final long serialVersionUID = -6849794470754667710L; //slightly... }
Use constants to assign values to String variables directly, no matter in several places or several times, they all use the same data.
Unless new a new String.
public class StringTest { public static void main(String[] args) { String s1 = "abcd"; String s2 = "abcd"; String s3 = new String("abcd"); String s4 = new String("abcd"); System.out.println("Assign two constants\t s1==s2:" + (s1 == s2)); System.out.println("Constants and new objects\t s1==s3:" + (s1 == s3)); System.out.println("Two new objects\t s3==s4:" + (s3 == s4)); } }
Output
Assign two constants s1==s2:true Constants and new objects s1==s3:false Two new objects s3==s4:false
Add something after the above code, try to modify the value of s1.
public class StringTest { public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { String s1 = "abcd"; String s2 = "abcd"; String s3 = new String("abcd"); String s4 = new String("abcd"); System.out.println("Assign two constants\t s1==s2:" + (s1 == s2)); System.out.println("Constants and new objects\t s1==s3:" + (s1 == s3)); System.out.println("Two new objects\t s3==s4:" + (s3 == s4)); //Get the value field hidden by String through reflection Field f = String.class.getDeclaredField("value"); //Let it open up f.setAccessible(true); //Get the internal value array of s1 char[] v = (char[]) f.get(s1); //change its first letter v[0] ='x'; System.out.println("After the change..."); System.out.println("s1 = "+ s1); System.out.println("s2 = "+ s2); System.out.println("s3 = "+ s3); System.out.println("s4 = "+ s4); System.out.println("Assign two constants\t s1==s2:" + (s1 == s2)); System.out.println("Constants and new objects\t s1==s3:" + (s1 == s3)); System.out.println("Two new objects\t s3==s4:" + (s3 == s4)); } }
Output
Assign two constants s1==s2:true Constants and new objects s1==s3:false Two new objects s3==s4:false After the change... s1 = xbcd s2 = xbcd s3 = xbcd s4 = xbcd Assign two constants s1==s2:true Constants and new objects s1==s3:false Two new objects s3==s4:false
1. The value inside the String can really be changed through reflection. 2. Directly changing the value will cause other String objects with the same value to be changed (so can guess the same data actually used at the bottom layer?) 3. Although the values are all changed, But as an object, the relationship between the 4 variables has not changed (the two Strings of new and the other two are still not equal) 4. It is dangerous to do this 5. It is boring to do so