1.JVM的方法区有个常量池,常量池中有字符串缓存池,还有Byte、Short、Integer、Long、Float、Double、Character等的缓存池。
用直接量创建的字符串会存放在字符串缓存池里
String s = "hello"; System.out.println(s.hashCode()); String s2 = "hello"; System.out.println(s.hashCode()); System.out.println(s == s2);//true
最后一句输出true,说明s和s2引用了字符串缓存池中同一个字符串
2.用new创建的字符串,首先字符串缓存池会缓存这个字符串,然后还会在堆区创建String对象
String s = "hello"; System.out.println(s.hashCode()); String s2 = new String("hello"); System.out.println(s.hashCode()); System.out.println(s == s2);//false
最后一句输出false,说明s2引用的是堆区的字符串对象。
另外,s和s2的hashcode是一样的,说明hashcode仅仅表示哈希函数的运算结果,不能代表对象的存储地址。只要两个字符串值一样,其hashcode就相等。
3.String类的intern()方法
当调用 intern 方法时,如果池已经包含一个等于此 String
对象的字符串(用 equals(Object)
方法确定),则返回池中的字符串。否则,将此 String
对象添加到池中,并返回此 String
对象的引用。
String ss = "abc"; String ss2 = new String("abc"); System.out.println(ss == ss2.intern());//true System.out.println(ss2 == ss.intern());//false
ss2.intern()时,对象池中已有"abc"这个String对象,所以直接返回常量池中该对象的引用,故相等。
ss.intern()时,ss本身就在池中,返回对象本身,故不相等