在定义 String str = "abc";
首先会到数据共享区中查找是否存在"abc",
存在,指向
如果不存在,创建
并不会像堆一样,在使用完后,被立即回收
构造器:
1.字节数组
byte [] bs = {97,101,98,110,99,103};
String str = new String(bs)
2.字符数组
char [] cs = {'a','e','c','r','k'};
String str = new String(cs)
区别:
//创建常量的字符串
String a = "abc";
//创建字符串的对象
String b = new String("abc");
//判断1
System.out.println(a == b);
//false,比较的是内存地址,一个是对象的地址,一个是常量字符串的地址
//String a 是在数据共享区创建的一个对象
//String b 是在堆中创建的字符串的对象,并指向数据共享区的
//判断2
System.out.println(a.equals(b));
//true比较的是内容
![](https://img.haomeiwen.com/i11687170/e569e8431169ce3e.png)
String c = "hello";
String d = "hello";
System.out.println(c == d);
//true,数据共享区中的内存地址一致
String e = "hello";
String f = "world";
String g = "helloworld";
System.out.println( g == ( e + f ));
//
String + 是通过StringBuilder.toString()的方法生成的
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
通过查看StringBuilder的toString()的方法,可以看到这里是通过new关键字来生成一个String对象,所以b指向的应该是堆中的字符对象。至于这个堆中的字符串对象和常量池中的字面量的关系,暂时还不太清楚。可能是通过clone的方式,在堆中新生成了一个字符串对象实现的。
Tip:
代码中的字符串拼接符号 +
会被编译器重载为StringBuilder的append()方法以提高性能
对于那些在编译时就能确定的字面量都会存放在运行时常量池中,比如:
String c = "hello " + "world"; //JVM会将此代码优化为String c = "hello world";
String b = a + "world";
其中a是变量,在编译时不能确定值,所以不会被放在运行时常量池中,而是在heap中重新new了一块儿内存。
网友评论