2024-11-07 04:13:10
这要和String的JVM内部工作原理相结合!
比如:String s1="accp"
Java内部将此语句转化为以下几个步骤:
(1)先定义一个名为s1的对String类的对象引用变量放到栈中:String s1;
(2)在常量池(字符串常量池)中查找有没有存放值为"accp"的地址,如果没有,则开辟一块存放字面值为"accp",并将这一块内存的指向地址放到栈中s1的变量中。如果已经有了值为"accp"的地址,则直接返回这个地址给栈中s1变量。所以如果常量池中已经有的值,直接返回地址就好。
String s1 = "accp"; 其字符串值是保存了一个指向常量池中值的引用!
所以s1 和s2的引用地址是相同的,所s1==s2为true
------------------------------------------------------------------------------
而Strings3=newString(s1);
(1)先定义一个名为s3的对String类的对象引用变量放到栈中:String s3;
(2)在堆中创建一个String类型的对象,这个对象的值,也就是s1的字面值为“accp”。会按照上面的第2的操作到常量池中获取,并返回一个常量池的引用给堆中的这个对象。
(3) 将堆中创建对象的地址返回给栈中变量s3。
所以 Strings3=newString(s1); 是一个指向堆中对象的引用地址。那么 s1 == s3 为false
下面给一个图更好理解吧:
==是比较对象的引用地址,如果要比较对象的值的话用equal吧!
----------扩展-------------------------------------------------------------------
String有一个方法intern(),返回的是这个String对象的常量池引用对象。
如果用
String s4 = s3.intern();
String s5= new String(s1).intern();
则 s1 == s4 和 s1 == s5 都为true
--------备注------------------------------------------------------------------------
这个问题以前的答案由于本人的经验和能力的不足,导致回答有很多错误的地方,在此表示非常抱歉。
2024-11-07 08:32:09
2024-11-07 05:21:57