日期:2014-05-20  浏览次数:20848 次

Java中StringBuilder转化为字符串之后,相等比较的问题
代码如下:

public static void main(String[] args) {
StringBuilder orgin = new StringBuilder("12321");
String sOrgin = orgin.toString();
StringBuilder orgin2 = orgin.reverse();
String sOrgin2 = orgin2.toString();
System.out.println(sOrgin==sOrgin2);
                System.out.println(sOrgin.equals(sOrgin2));
}

运行结果,第一个是false,第二个是true。

现在想问的是,第一个结果为何是false,在执行String sOrgin = orgin.toString();之后,sOrgin是栈上的引用,orgin.toString()还是堆上的空间吗。从结果上看貌似是的,堆上的字段进行运算之后还是分配在堆上是吗 自己不太明白。

------解决方案--------------------
你可以这么想,栈内存里面只存基本数据类型和地址
所有生成的新对象都是在堆内存中。
reverse方法生成了一个新的stringbuilder,也就是在生成的新的堆内存,所以sOrgin2和sOrgin这两个变量指向的地址不一样
------解决方案--------------------
引用:
你可以这么想,栈内存里面只存基本数据类型和地址
所有生成的新对象都是在堆内存中。
reverse方法生成了一个新的stringbuilder,也就是在生成的新的堆内存,所以sOrgin2和sOrgin这两个变量指向的地址不一样

额。。有点错误,应该是tostring方法生成了新的字符串,他的地址是在字符串常量池中。
因为两次调用tostring时字符串的不相同,所以也就生成了两个地址。。
而sOrgin.equals(sOrgin2)为真,是因为他们还是一个对象,你可以试试sOrgin2 == sOrgin的结果
------解决方案--------------------
关键是toString方法中是new 一个字符串对象,和reserve无关,重复toString方法获得的String对象都不是一个对象。
楼上的解释还是有点问题,String对象直接赋值是给的常量池里的字符串对象地址,但是new操作时,会拷贝常量池里的字符串对象,这个时候拿到的其实是这个新的拷贝对象的地址。


String a = new String("1");
String b = new String("1");
System.out.println(a==b);//这个一样返回false

------解决方案--------------------
只要是new操作出来的字符串,他的引用就肯定不一样,这个和字符串在字符串常量池中是不是同一个无关系。
------解决方案--------------------
要想比较值就得用equals。
------解决方案--------------------
StringBuffer 的toString是生成一个新的字符串,但是StringBuffer其本身没有变化。然后反向之后再toString,又生成一个String的。
LZ可以试试如下代码:
		StringBuffer sb = new StringBuffer("abc");

String str1 = sb.toString();
String str2 = sb.toString();

System.out.println(str1 == str2);