java中的字符串到底是在方法区的常量池里还是new出来的对象里

Posted 稚枭天卓

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java中的字符串到底是在方法区的常量池里还是new出来的对象里相关的知识,希望对你有一定的参考价值。

String实质是字符数组,两个特点:1、该类不可被继承;2、不可变性(immutable)

例如 String s1 = new String("myString");

和 String s1 = "myString"; 

第一种方式通过关键字new定义过程:在程序编译期,编译程序先去字符串常量池检查,是否存在“myString”,如果不存在,则在常量池中开辟一个内存空间存放“myString”;如果存在的话,则不用重新开辟空间,保证常量池中只有一个“myString”常量,节省内存空间。然后在内存堆中开辟一块空间存放new出来的String实例,在栈中开辟一块空间,命名为“s1”,存放的值为堆中String实例的内存地址,这个过程就是将引用s1指向new出来的String实例

第二种方式直接定义过程:在程序编译期,编译程序先去字符串常量池检查,是否存在“myString”,如果不存在,则在常量池中开辟一个内存空间存放“myString”;如果存在的话,则不用重新开辟空间。然后在栈中开辟一块空间,命名为“s1”,存放的值为常量池中“myString”的内存地址

转载自:https://zhidao.baidu.com/question/1431032825282549579.html

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

就速度来说,有如下关系: 

    寄存器 > 栈 >堆 >其他

这里我们主要关心栈,堆和常量池,对于栈和常量池中的对象可以共享,对于堆中的对象不可以共享。栈中的数据大小和生命周期是可以确定的,当没有引用指向数据时,这个数据就会消失。堆中的对象的由垃圾回收器负责回收,因此大小和生命周期不需要确定,具有很大的灵活性。

 

    对于字符串:

其对象的引用都是存储在栈中的,

如果是编译期已经创建好(即直接用双引号定义的)的就存储在常量池中

如果是运行期(即new出来的)才能确定的就存储在堆中

对于equals相等的字符串,在常量池中永远只有一份,在堆中有多份。

 

如以下代码:

Java代码  

String s1 = "china";  

String s2 = "china";  

String s3 = "china";  

String ss1 = new String("china");  

String ss2 = new String("china");  

String ss3 = new String("china");  

 

对于通过 new 产生一个字符串(假设为 ”china” )时,会先去常量池中查找是否已经有了 ”china” 对象,如果没有则在常量池中创建一个此字符串对象,然后堆中再创建一个常量池中此 ”china” 对象的拷贝对象。并把ss1指向堆中的地址。(在常量池中创建目的是为了提升字符串的访问效率

 

再例子:

 

 

 
  1. String s5 = new String("Hello"); //先在常量池中创建,再在堆中创建,返回的数值s5是堆中的地址

  2. String s6 = s5.intern();         //返回的数值s6 ,是常量池中的地址

  3. String s10 = "Hello";            //返回的数值s10,是常量池中的地址

  4.  
  5. System.out.println(s5 == s6);  //输出false

  6.  
  7. System.out.println(s6 == s10); //输出true

 

 

 

这也就是有道面试题:

 String s = new String(“xyz”); 产生几个对象?一个或两个,如果常量池中原来没有 ”xyz”, 就是两个。

 

对于基础类型的变量和常量:变量和引用存储在栈中,常量存储在常量池中。

 

转载自:https://blog.csdn.net/u012031380/article/details/54981472

以上是关于java中的字符串到底是在方法区的常量池里还是new出来的对象里的主要内容,如果未能解决你的问题,请参考以下文章

JDK1.8字符串常量池里存的是String对象还是引用?

java方法区中包含哪些内容,常量池中包含哪些内容

Java String的点滴1

方法区的回收

java运行时数据区域

Java你可能不知道的事系列1