1.String 对象的两种创建方式
String 对象的两种创建方式是有区别的,一个是从常量池里拿数据,另一个是从直接在堆内存空间创建一个新的对象。如下所示:
public static void main(String[] args) {
String a = "123";//先检查字符串常量池中有没有"123",如果字符串常量池中没有,则创建一个,然后a指向字符串常量池中的数据,如果有,则直接将a指向"123"";
String b = "123";
String c = new String("123");//在堆中创建一个新对象
String d = new String("123");
//"=="比较的是地址值
System.out.println(a==b);//true
System.out.println(a==c);//false
System.out.println(c==d);//false
}
可以看到同样是使用String创建的,变量a和c被储存在不同的地方。
注:使用了new 方法,便需要创建新的对象
2.String的常量池
- 直接使用双引号声明出来的String对象会直接存储在常量池。
- 如果不是用双引号声明的String对象,可以使用String提供的intern方法。
String.intern() 是一个 Native 方法,它的作用是:如果运行时常量池中已经包含一个等于此 String 对象内容的字符串,则返回常量池中该字符串的引用。
public static void main(String[] args) {
String a = "123";先检查字符串常量池中有没有"123",如果字符串常量池中没有,则创建一个,然后a指向字符串常量池中的数据,如果有,则直接将a指向"123"";
String b = "123";
String c = new String("123");//在堆中创建一个新对象
String d = new String("123");
String e = c.intern();//使用String提供的intern方法
//"=="比较的是地址值
System.out.println(a==b);//true
System.out.println(a==c);//false
System.out.println(c==d);//false
//使用String提供的intern方法:c没有使用intern时,a和c的地址值不同;使用了intern,a和c的地址值相同
System.out.println(a==e);//true
}
3.参考资料
https://tech.meituan.com/2014/03/06/in-depth-understanding-string-intern.html
https://www.journaldev.com/797/what-is-java-string-pool