常量池与new之String str2 = "hello world" 与 String str4 = new String("hello world");

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/CXHPLY/article/details/49403587

注:比较运算符== :两个字符串的地址是否相同。

情景1:

String str1 ="hello world";

Stringstr2 ="hello world";

System.out.println("(str1 == str2)? "+ (str1 == str2));

结果:true

String常量池

        Java中的常量池技术是为了方便快捷地创建某些对象而出现的,当需要一个对象时,便可从池中取一个出来(若池中没有则创建该对象),所以在需要重复创建相等变量时节省了许多时间。常量池实际也是一个内存空间,不同于使用new关键字创建的对象所在的堆空间。在class文件中有一部分来存储编译期间生成的字面常量以及符号引用,这部分叫做class文件常量池,在运行期间对应着方法区的运行时常量池。

  因此String str1 = "helloworld"; String str2 = "hello world"; 都在编译期间生成了字面常量和符号引用,运行期间字面常量"helloworld"被存储在运行时常量池(当然只保存了一份)。通过这种方式来将String对象跟引用绑定的话,JVM执行引擎会先在运行时常量池查找是否存在相同的字面常量,如果存在,则直接将引用指向已经存在的字面常量;否则在运行时常量池开辟一个空间来存储该字面常量,并将引用指向该字面常量。

        str1与str2指向常量池同一存储空间,所以为true。

 

情景2:

Stringstr3 =newString("hello world");

Stringstr4 =newString("hello world");

System.out.println("(str3 == str4)? "+ (str3 == str4));

结果:false

通过new关键字来生成对象是在堆区进行的,而在堆区进行对象生成的过程是不会去检测该对象是否已经存在的。因此通过new来创建对象,创建出的一定是不同的对象,即使字符串的内容是相同的。

 

情景3:

Stringstr1 ="hello world";

Stringstr3 =newString("hello world");

System.out.println("(str1 == str3)? " + (str1 == str3));

结果:false

1) 栈中开辟一块空间存放引用str1;

2) String池中开辟一块空间,存放String常量"hello world";

3) 引用str1指向池中String常量"hello world",指代的地址即常量"hello world"所在地址;

4) 栈中开辟一块空间存放引用str3;

5) 堆中开辟一块空间存放一个新建的String对象"hello world";

6) 引用str3指向堆中的新建的String对象"hello world";

7) str3所指代的对象地址为堆中地址,而str1地址在池中,输出为false;

 

情景4:

        String str4 = new String("hello world");

        Stringstr5 = str4;

        System.out.println("(str4 == str5)? " + (str4 == str5));

结果:true

1) 栈中开辟一块空间存放引用str4;

2) 堆中开辟一块空间存放一个新建的String对象" hello world";

3) 引用str4指向堆中的新建的String对象"abc";

4) 栈中开辟一块空间存放引用str5;

5) 引用str5指向引用str4;

6) str4,str5所指代的对象地址为堆中地址,且相等,故为true;

猜你喜欢

转载自blog.csdn.net/CXHPLY/article/details/49403587
今日推荐