String 字符串常量
StringBuffer 字符串变量(线程安全)
StringBuilder 字符串变量(非线程安全)
String.intern()方法
Returns a canonical representation of the string object. A pool of strings, initially empty, is maintained privately by the class String. When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned. It follows that for and two strings s and t, s.intern()==t.intern() is true if and only if s.equals(t) is true. All literal strings and string-valued constant expressions are interned.
String.intern()方法在jdk1.7之前,字符串常量存储在方法区的PermGen Space。在jdk1.7之后,字符串常量重新移到堆中。
JAVA面试题(上)https://blog.csdn.net/jackfrued/article/details/44921941中的一个问题
String s1=new StringBuilder("go").append("od").toString();
System.out.println(s1.intern()==s1);
String s2=new StringBuilder("ja").append("va").toString();
System.out.println(s2.intern()==s2);
运行结果:
jdk1.7: true; false
jdk1.6: false; false
原因:
返回的都是对象的引用(指针)
jdk1.6:字符串常量存储在方法区中,StringBuilder创建的字符串实例在java堆上
jdk1.7:对str1 true,都在java堆上。对str2 false,因为“java”这个字符串在执行StringBuilder.toString()之前已经出现过,字符串常量池中已经有它的引用("java"这个字符串特殊而已)。
String s1=new StringBuilder("go").append("od").toString();
System.out.println(s1.intern()==s1);
String s2=new StringBuilder("go").append("od").toString();
System.out.println(s2.intern()==s2);
jdk1.7 结果:true; false
String s1=new StringBuilder("go").append("od").toString();
System.out.println(s1.intern()==s1);
String s2=new StringBuilder("he").append("llo").toString();
System.out.println(s2.intern()==s2);
jdk1.7结果:true; true