在进一步解读String类时,先了解下内存分配和数据存储的。
数据存储
1.寄存器:最快的存储区,位于处理器的内部。由于寄存器的数量有限,所以寄存器是按需分配。
2.堆栈:位于RAM中,但是通过堆栈指针可以从处理器哪里获得直接支持。堆栈指针向下移动,则分配新的内存;堆栈指针向上移动释放内存。
注:堆栈中存储基本的数据类型和【对象引用】,但是Java对象存储在堆中。
3.堆:通用内存池,位于RAM中,用于存放所有的Java对象。
注:堆中存储的 new创建的对象和数组。
4.常量存储:存放常量。
5.非RAM存储:数据不依赖于程序而存在。如:流对象和持久化对象
实例验证
String a = "test"; String b = "test";
其中"test"存储在String pool常量池中,String类的对象引用变量a和b存储在堆栈中。由于常量池中常量具有唯一性,所以引用对象a和b指向常量池中同一个常量"test"。
由此可知,上述代码的处理过程:
首先会在堆栈中创建一个String类的对象引用变量a,然后检查字符串常量池中是否含有"test",若没有则将"test"存放到字符串常量池中,同时将变量a指向"test";
当创建变量b的时候,做同样的处理操作,这是就不会重新在字符串常量池中增加"test",而是直接将变量b指向"test"。
综上得知:
第一行代码中:String a = "test";将产生一个对象和一个引用。
第二行代码中:String b = "test";则只会产生一个引用。
接着上面的示例
String c = new String("test"); String d = new String("test");
首先看String c = new String("test"); 这一段代码:
第一步:在堆栈中创建String类的对象引用变量c。
第二步:使用new创建对象,将在堆中创建新的String对象,同时检查字符串常量池中是否含有"test",没有就创建
第三步:将变量c指向堆中的对象
由于new操作,每次都会产生新的对象,所以String d = new String("test");执行的操作步骤和上面的执行步骤一致。
由上面两个例子可知:
System.out.println("a = b ?" + (a == b)); System.out.println("c = d ?" + (c == d));
输出结果:
a = b ? true c = d ? false
String最后一篇,将来讲述字符串的拼接,以及String,StringBuilder,StringBuffer的区别。
作者:江南久无雪
源码记:苦人所不苦,能人所不能,所谓成也
声明:原创博客请在转载时保留原文链接或者在文章开头加上本人博客地址,如发现错误,欢迎批评指正。