public class StringEditor {
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
String str1 = "Hello";
String str2 = new String("Hello");
String sub = str2.substring(3);
// str1 is directly pointing to String in String pool but str2 is pointing to the object created in heap
// which is having the value of 'Hello'. So if we make any change to 'Hello' in String pool, str2 value will
// not be impacted. But if we point str2 to 'Hello' of String pool by using intern then value of str2 will be
// impacted. intern() returns the string from the pool, so if we dont assign it to str2 then again value of str2
// will not be impacted.
str2 = str2.intern();
System.out.println(str1 == str2);
System.out.println("Current value of str1 & str2 : " + str1);
Field fStr = String.class.getDeclaredField("value");
fStr.setAccessible(true);
char[] chr = (char[])fStr.get(str1);
char[] suba = (char[])fStr.get(sub);
// Value of suba printed below will depend on the jre being used to execute this file
// prior to jre7 it will give whole value of the parent string str2, though it is using
// only 2 of its characters causing the memory leak, but this behavior has been corrected
// from jre7, so from jre7 it will give only 2 characters.
System.out.println(Arrays.toString(suba));
chr[1] = 'i';
chr[2] = '\u0000';
chr[3] = '\u0000';
chr[4] = '\u0000';
char[] newChar = new char[10];
newChar[0] = 'I';
newChar[1] = ' ';
newChar[2] = 'A';
newChar[3] = 'M';
newChar[4] = ' ';
newChar[5] = 'N';
newChar[6] = 'I';
newChar[7] = 'T';
newChar[8] = 'I';
newChar[9] = 'N';
fStr.set(str1, newChar);
System.out.println("After change value of str1 : " +str1);
System.out.println(str2);
System.out.println("Still str1 & str2 are equal : " + (str1==str2));
}
}
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
String str1 = "Hello";
String str2 = new String("Hello");
String sub = str2.substring(3);
// str1 is directly pointing to String in String pool but str2 is pointing to the object created in heap
// which is having the value of 'Hello'. So if we make any change to 'Hello' in String pool, str2 value will
// not be impacted. But if we point str2 to 'Hello' of String pool by using intern then value of str2 will be
// impacted. intern() returns the string from the pool, so if we dont assign it to str2 then again value of str2
// will not be impacted.
str2 = str2.intern();
System.out.println(str1 == str2);
System.out.println("Current value of str1 & str2 : " + str1);
Field fStr = String.class.getDeclaredField("value");
fStr.setAccessible(true);
char[] chr = (char[])fStr.get(str1);
char[] suba = (char[])fStr.get(sub);
// Value of suba printed below will depend on the jre being used to execute this file
// prior to jre7 it will give whole value of the parent string str2, though it is using
// only 2 of its characters causing the memory leak, but this behavior has been corrected
// from jre7, so from jre7 it will give only 2 characters.
System.out.println(Arrays.toString(suba));
chr[1] = 'i';
chr[2] = '\u0000';
chr[3] = '\u0000';
chr[4] = '\u0000';
char[] newChar = new char[10];
newChar[0] = 'I';
newChar[1] = ' ';
newChar[2] = 'A';
newChar[3] = 'M';
newChar[4] = ' ';
newChar[5] = 'N';
newChar[6] = 'I';
newChar[7] = 'T';
newChar[8] = 'I';
newChar[9] = 'N';
fStr.set(str1, newChar);
System.out.println("After change value of str1 : " +str1);
System.out.println(str2);
System.out.println("Still str1 & str2 are equal : " + (str1==str2));
}
}