1. 先来说说两个用于测试比较的工具:
str1.equals(str2) --比较字符串内容(内容相同,不代表是同一个对象)
str1==str2 --比较字符串引用(引用相同,指向的对象也相同)
附:
str.hashCode() --返回字符串的哈希码,对于String类,只要字符串一样,返回的哈希码也是一样
System.indentityHashCode() --返回内存地址级别的哈希码,如果字符串一样但是对象不一样,返回的哈希码不一样。必须是同一个对象才会返回相同值
2. 字符串常量池 和 对象堆
使用new String(str1) 会在对象堆创建对象存储字符串。下文简称对象
使用new String(str1).intern() 会先去找常量池是否存在该字符串数据,存在则直接引用常量池的数据,不存在就会在常量池创建一个。
使用"str1" 会在常量池开辟内存存储字符串,Java会保证常量池只有一份相同的字符串数据。下文简称常量(必须是编译器能提前知道的)
常量+常量=常量
* + 对象 = 对象
引用+常量=对象
举例:(Java6 和 Java7 的运行的结果不大一样, String.intern() 在java6,7,8定义也许不一样,不要随便使用,会造成OutOfMemoryError的)
package string.intern;
public class TestStringIntern {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String a = new String("aaa");
String b = new String("aaa");
String c = new String("aaa").intern();
String d = "aaa";
String e = "aaa";
String f = "aaa".intern();
String g = a + b;//new Object
String h = a + c;//new Object
String i = a + d;//new Object
String j = c + d;
String k = d + e;
String l = e + f;
prints("----------a!=b!=c------------");
print(a==b);
print(a==c);
print(a==d);
prints("----------c==d==e==f---------");
print(c==d);
print(d==e);
print(d==f);
prints("----------");
print(g==h);
print(g==i);
print(g==j);
print(g==k);
prints("");
print(j==k);
print(k==l);
prints("");
print(k.intern()==k);
print(k.intern()==(new String("aaa").intern()+"aaa"));
print(k.intern()==("aaa"+"aaa"));
}
public static void print(boolean b) {
System.out.println(b);
}
public static void prints(String s) {
System.out.println(s);
}
}
输出结果:
----------a!=b!=c------------
false
false
false
----------c==d==e==f---------
true
true
true
----------
false
false
false
false
false
false
false
false
true
如何知道一个字符串对象是否在常量池里面? (str.intern() == str 即可!)
注意,在常量池的也是对象噢。