Java中字符串(String)的存储和赋值原理

可能很多java的初学者对String的存储和赋值有迷惑,以下是一个很简单的测试用例,你只需要花几分钟时间便可理解。

1.在看例子之前,确保你理解以下几个术语:

 

 :由JVM分配区域,用于保存线程执行的动作和数据引用。栈是一个运行的单位,Java中一个线程就会相应有一个线程栈与之对应。

 

 :由JVM分配的,用于存储对象等数据的区域。

 

常量池 :在堆中分配出来的一块存储区域,用于存储显式 的String,float或者integer.例如String str="abc"; abc这个字符串是显式声明,所以存储在常量池。

 

2.看这个例子,用JDK5+junit4.5写的例子,完全通过测试

Java代码

 

  1. import static org.junit.Assert.assertNotSame;   
  2. import static org.junit.Assert.assertSame;   
  3.   
  4. import org.junit.Test;   
  5.   
  6. /**
  7. * @author Heis
  8. *
  9. */  
  10. public class StringTest{   
  11.   
  12.     @Test  
  13.     public void testTheSameReference1(){   
  14.          String str1="abc";   
  15.          String str2="abc";   
  16.          String str3="ab"+"c";   
  17.          String str4=new String(str2);   
  18.            
  19.         //str1和str2引用自常量池里的同一个string对象   
  20.          assertSame(str1,str2);   
  21.         //str3通过编译优化,与str1引用自同一个对象   
  22.          assertSame(str1,str3);   
  23.         //str4因为是在堆中重新分配的另一个对象,所以它的引用与str1不同   
  24.          assertNotSame(str1,str4);   
  25.      }   
  26.        
  27. }  

 

  • 第一个断言很好理解,因为在解析的时候,"abc"被存储在常量池中,str1和str2的引用都是指向常量池中的"abc"。所以str1和str2引用是相同的。
  • 第二个断言是由于编译器做了优化,编译器会先把字符串拼接,再在常量池中查找这个字符串是否存在,如果存在,则让变量直接引用该字符串。所以str1和str3引用也是相同的。
  • str4的对象不是显式赋值的,编译器会在堆中重新分配一个区域来存储它的对象数据。所以str1和str4的引用是不一样的。

 

 

 

String在对在编译时可以确定的常量会做一定的优化,把其放在字符串常量池中。

+ 和 new出来的对象都是存储在堆内

对象引用都是存储在栈内

String a = "a";

 这条语句在执行的时候,会在常量池内创建一个String对象,内容为a,a指向这个对象。

String ab5 = new String("ab");

 这条语句在执行的时候,会先去常量池内查找有没有值为ab的对象,没有的话,就创建,有的话,就在堆上面创建一个新的对象,内容是ab,ab5指向这个在堆上创建的对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值