String存放在堆中还是栈中?5年的Java照样说不清楚!

作者:Java从入门到架构 师

来源:http://suo.im/6a8aZe

在Java中,字符串是特殊的。Java特别注意字符串类型,其他类型则没有这种类型。例如,要创建字符串对象,您无需使用“ new ”关键字。要创建其他类型的对象,必须使用“ new”关键字。像这样,字符串受到Java的特别注意。这种注意值得一阵,因为在开发任何类型的应用程序时,几乎在所有地方都使用了字符串。

在将字符串对象也存储在内存中的同时,Java对它们进行了特殊处理。阅读本文之后,您将了解如何在内存中对它们进行特殊处理。

众所周知,JVM将分配给Java程序的内存分为两部分。一个是堆栈,另一个是堆。堆栈用于执行目的,堆用于存储目的。在该堆内存中,JVM分配了一些专门用于字符串文字的内存。堆内存的这一部分称为字符串常量池。

每当您使用字符串文字创建字符串对象时,该对象都会存储在字符串常量池中,而每当您使用new关键字创建字符串对象时,此类对象都会存储在堆内存中。

例如,当您创建如下所示的字符串对象时,它们将存储在字符串常量池中。

String s1 = "abc";

String s2 = "xyz";

String s3 = "123";

String s4 = "A";

并且当您使用如下所示的new关键字创建字符串对象时,它们将存储在堆内存中。

String s5 = new String("abc");

char[] c = {'J', 'A', 'V', 'A'};

String s6 = new String(c);

String s7 = new String(new StringBuffer());

这就是字符串常量池在内存中的外观。

关于字符串常量池的另一件有趣的事情是,根据对象的内容将池空间分配给对象。池中不会有两个对象具有相同的内容。

当您使用字符串文字创建字符串对象时,就会发生这种情况,

“当您使用字符串文字创建字符串对象时,JVM首先检查要创建的对象的内容。如果池中存在具有相同内容的对象,则它将返回该对象的引用。它不会创建新对象。如果内容与现有对象不同,则只能创建新对象。”

但是,当您使用new关键字创建字符串对象时,无论内容是否相同,都会创建一个新对象。

这可以通过使用“ ==”运算符来证明。如果两个对象在内存中具有相同的物理地址,则“ ==”运算符将返回true,否则它将返回false。在下面的示例中,s1和s2使用字符串文字“ abc”创建。因此,s1 == s2返回true。其中,s3和s4是使用具有相同内容的新运算符创建的。但是,s3 == s4返回false。

public class StringExamples {
  public static void main(String[] args)
  {
            //Creating string objects using literals
   String s1 = "abc";
   String s2 = "abc";
   System.out.println(s1 == s2); //Output : true
   //Creating string objects using new operator
   String s3 = new String("abc");
   String s4 = new String("abc");
   System.out.println(s3 == s4); //Output : false
  }
 }

简单来说,字符串常量池中不能有两个内容相同的字符串对象。但是,堆内存中可以有两个内容相同的字符串对象。


好文章,我在看

  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值