一个初始为空的字符串池,它由类String独自维护。当调用 intern方法时,如果池已经包含一个等于此String对象的字符串(用equals(oject)方法确定),则返回池中的字符串。否则,将此String对象添加到池中,并返回此String对象的引用。 对于任意两个字符串s和t,当且仅当s.equals(t)为true时,s.intern() == t.intern()才为true。所有字面值字符串和字符串赋值常量表达式都使用 intern方法进行操作。
String str1 = new StringBuilder("测试").append("01").toString();
String str2 = new StringBuilder("测试").append("01").toString();
//true
System.out.println(str1.intern()==str1);
//false str1堆中地址 != str2
System.out.println(str1.intern()==str2);
//true str1在常量池的地址 == str2在常量池的地址
System.out.println(str1.intern()==str2.intern());
//false str1堆地址== str2堆地址
System.out.println(str1==str2);
- JVM对于将字符串放进字符串常量池是在编译期做的,所以第一步代码在编译时期池中只有“测试”和“01”两个对象(直接申明字面量才能在编译期就将字符串对象放入字符串池中,比如:
String str1 =“测试01”),而到了运行时才创建了“测试01”对象,此时在字符串常量池中是没有“测试01”的,所以当调用str1.intern()时,就会将str1这个对象复制到字符串池中,并且返回它在堆中的引用,所以str1.intern()==str1为true,而str1.intern()==str2是因为str1和str2在堆中的地址本来就不一样所以为false str1.intern()==str2.intern()为true是因为str1.intern返回的是str1在堆中的地址,而str2.intern返回的也是str1在堆中的地址str1==str2为false是因为他们两个在堆中的地址本来就不一样- intern方法在1.8中的说明是如果池已经包含一个等于此String对象的字符串,则返回池中的字符串。否则,将此String对象添加到池中,并返回此String对象堆中的引用