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

[新手提问]遇到String奇怪问题,苦思未果,请指点
参考了String的不变性以后,写了以下验证:

public   class   strConcat{
public   static   void   main(String[]   args){
String   str2=new   String( "ABC ");
String   str1= "ABC ";
String   str0= "ABC ";
//str1=str1+ "2_3_ ";
System.out.println( "str1: "+str1);
System.out.println( "str0: "+str0);
System.out.println( "str2: "+str2);
System.out.println( "str1==str0: "+str1==str0);
System.out.println( "str1==str0: "+String.valueOf(str1==str0));
System.out.println( "str1==str2: "+String.valueOf(str1==str2));
System.out.println( "str1   equals   str0: "+str1.equals(str0));
System.out.println( "str1   equals   str0: "+str1.equals(str0));
}
}

提问在楼下:

------解决方案--------------------
str2不是在栈里面,然后引用堆里面的 "ABC "么?
------解决方案--------------------
new String( "ABC ")直接在堆里创建 "ABC "
------解决方案--------------------
对象在堆里 程序执行时才创建
------解决方案--------------------
1.优先级问题:改为System.out.println(str1==str0);
新的对象会创建在 堆 中,对象的引用存储在 栈 中

当String str2 = new String( "ABC ");
会在常量池中存在一个 ABC的字符串 ,在堆中创建一个String的对象,在栈中存储 这个对象的引用str2;

常量池(constant pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量,Java会确保一个字符串常量只有一个拷贝
所以str1==str0是正确的

2.String.valueOf();是String的静态方法,在这里应该是首先计算 str1==str0 返回true后
由String.valueOf()将其转换为String在赋予+操作
------解决方案--------------------
对象总是在堆里的(除了常量池)
引用才分在堆里或者在栈里