一、引用变量与对象的区别
首先,根据我们实例bean对象过程知道,A aa;仅是声明了一个类A的引用变量,aa并不是一个对象,类的对象是通过 new来创建的。
所以,String s ....中s并不是一个对象,而是一个string类型的引用变量。
另外, 对于string字符串来讲,字符串文字本身是一个对象,如 "XXX",则 XXX就是一个对象。
二、文字池即缓冲池(pool of literal strings)和堆(heap)中的字符串对象
由于字符串对象的大量使用(一般而言对象总是在heap分配内存),java中为了节省内存空间和运行时间,例如在比较字符串时,==要比equals()快,所以在编译阶段就把所有的字符串文字放到一个文字池中,而在运行时文字池成为常量的一部分。文字池中所以相同的字符串常量会被合并,只占用一个空间。
通过以下两种方式可验证:
1、
// ==判断内容为两个对象的引用地址
//String s1 = "abc" 先在缓冲池查找是否已有abc对象,没有,会在缓冲池创建 abc对象,并把引用地址赋给s1;
// String s2 = "abc" 会先在缓冲池查找是否有abc对象,有则不创建,直接用已有abc对象,把引用地址赋给s2;
// 所以s1和s2的引用地址是一样的
String s1 = "abc";
String s2 = "abc";
if(s1 == s2){
//此处会输出内容
}
2、
//使用new创建string对象时,不管缓冲池和堆中是否已有abc对象,都会在堆中创建abc对象,并把堆中abc对象引用地址赋给string引用
// String s1 = new String("abc")在堆中创建abc对象,并把abc引用赋给s1
// String s2 = new String("abc")在堆中新创建一个abc对象,把新对象引用赋给s2
String s1 = new String("abc");
String s2 = new String("abc");
if(s1 == s2){
//此处无内容输出
}
三、String s = new String("abc")过程步骤(详见--String s = "abc"和String s = new String("abc")详解文章)
1) 栈中开辟一块空间存放引用str2;
2) 堆中开辟一块空间存放一个新建的String对象"abc";
3) 引用str2指向堆中的新建的String对象"abc";
4) str2所指代的对象地址为堆中地址,而常量"abc"地址在池中,