返回信息流关于Stringstr = "abc"的内部工作。Java内部将此语句转化为以下几个步骤:
(1)先定义一个名为str的对String类的对象引用变量:Stringstr;
(2)在栈中查找有没有存放值为"abc"的地址,如果没有,则开辟一个存放字面值为"abc"的地址,接着创建一个新的String类的对象o,并将o的字符串值指向这个地址,而且在栈中这个地址旁边记下这个引用的对象o。如果已经有了值为"abc"的地址,则查找对象o,并返回o的地址。
(3)将str指向对象o的地址。值得注意的是,一般String类中字符串值都是直接存值的。但像Stringstr = "abc";这种场合下,其字符串值却是保存了一个指向存在栈中数据的引用!
为了更好地说明这个问题,我们可以通过以下的几个代码进行验证。
复制内容到剪贴板代码:
?123 String str1 = "abc"; String str2 = "abc"; System.out.println(str1==str2); //true
注意,我们这里并不用str1.equals(str2);的方式,因为这将比较两个字符串的值是否相等。==号,根据JDK的说明,只有在两个引用都指向了同一个对象时才返回真值。而我们在这里要看的是,str1与str2是否都指向了同一个对象。
结果说明,JVM创建了两个引用str1和str2,但只创建了一个对象,而且两个引用都指向了这个对象。
我们再来更进一步,将以上代码改成:
复制内容到剪贴板代码:
?12345 String str1 = "abc"; String str2 = "abc"; str1 = "bcd"; System.out.println(str1 + "," + str2); //bcd, abc System.out.println(str1==str2); //false
这就是说,赋值的变化导致了类对象引用的变化,str1指向了另外一个新对象!而str2仍旧指向原来的对象。上例中,当我们将str1的值改为"bcd"时,JVM发现在栈中没有存放该值的地址,便开辟了这个地址,并创建了一个新的对象,其字符串的值指向这个地址。
大神解释解释这段话吧。。。看的晕呼呼的
这是一条镜像帖。来源:北邮人论坛 / java / #27364同步于 2013/10/14
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
关于String的问题
z843259180
2013/10/14镜像同步4 回复
订阅后,新回复会通过你的通知中心匿名送达。
4 条回复
和Java常量池和String Interning有关。见http://bbs.byr.cn/#!article/Java/24734
但是,字符串还是不要用==判断相等吧。用.equals。
前边一种情况:"abc"字符串是被初始化在数据区的,是和static常量同时被初始化的。所以str1和str2上的引用都没指向堆空间,而是同时指向了数据区中的"abc"常量,所以两个值会相等
后边一种情况:"abc","bcd"两个字符串在数据区中是两个不同的地址,str1指向的是bcd的地址,str2指向的是abc的地址。。肯定不一样。。
另外,判断两个是不是相等的话,印象中有的是重写的equals方法,有的重写的是hascode方法,具体实现好像还是要看api的。。
如果说的不对,求@nuanyangyang 学姐/妹大神吐槽。。
【 在 z843259180 的大作中提到: 】
: 关于Stringstr = "abc"的内部工作。Java内部将此语句转化为以下几个步骤:
: [color=#DC143C](1)先定义一个名为str的对String类的对象引用变量:Stringstr;
: (2)在栈中查找有没有存放值为"abc"的地址,如果没有,则开辟一个存放字面值为"abc"的地址,接着创建一个新的String类的对象o,并将o的字符串值指向这个地址,而且在栈中这个地址旁边记下这个引用的对象o。如果已经有了值为"abc"的地址,则查找对象o,并返回o的地址。
: ...................
在这里回答一下你说的关于“有的是重写的equals方法,有的重写的是hascode方法”。java规定是,如果两个对象equals返回true,那么hashcode返回值必须相等;反之则不然,即equals就算返回false,hashcode也可以相等。
【 在 tdanieln 的大作中提到: 】
: 前边一种情况:"abc"字符串是被初始化在数据区的,是和static常量同时被初始化的。所以str1和str2上的引用都没指向堆空间,而是同时指向了数据区中的"abc"常量,所以两个值会相等
: 后边一种情况:"abc","bcd"两个字符串在数据区中是两个不同的地址,str1指向的是bcd的地址,str2指向的是abc的地址。。肯定不一样。。
: 另外,判断两个是不是相等的话,印象中有的是重写的equals方法,有的重写的是hascode方法,具体实现好像还是要看api的。。
: ...................