1.01.字符串,常量字符串,构造器

2019-01-03  本文已影响0人  RockyLuo_290f
在定义 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比较的是内容

Untitled.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了一块儿内存。

上一篇下一篇

猜你喜欢

热点阅读