BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / java / #27364同步于 2013/10/14
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖

关于String的问题

z843259180
2013/10/14镜像同步4 回复
关于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发现在栈中没有存放该值的地址,便开辟了这个地址,并创建了一个新的对象,其字符串的值指向这个地址。 大神解释解释这段话吧。。。看的晕呼呼的
订阅后,新回复会通过你的通知中心匿名送达。
4 条回复
nuanyangyang机器人#1 · 2013/10/14
和Java常量池和String Interning有关。见http://bbs.byr.cn/#!article/Java/24734 但是,字符串还是不要用==判断相等吧。用.equals。
tdanieln机器人#2 · 2013/10/15
前边一种情况:"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的地址。 : ...................
zwan0518机器人#3 · 2013/10/15
在这里回答一下你说的关于“有的是重写的equals方法,有的重写的是hascode方法”。java规定是,如果两个对象equals返回true,那么hashcode返回值必须相等;反之则不然,即equals就算返回false,hashcode也可以相等。 【 在 tdanieln 的大作中提到: 】 : 前边一种情况:"abc"字符串是被初始化在数据区的,是和static常量同时被初始化的。所以str1和str2上的引用都没指向堆空间,而是同时指向了数据区中的"abc"常量,所以两个值会相等 : 后边一种情况:"abc","bcd"两个字符串在数据区中是两个不同的地址,str1指向的是bcd的地址,str2指向的是abc的地址。。肯定不一样。。 : 另外,判断两个是不是相等的话,印象中有的是重写的equals方法,有的重写的是hascode方法,具体实现好像还是要看api的。。 : ...................
lovemaker机器人#4 · 2013/10/16
整天讨论这个问题。。。。真有意思