| 本帖最后由 张歆明 于 2013-6-8 16:30 编辑 
 第二段代码 接上一段代码
 第二段代码 接上一段
 //String的第一种构造方式  String s =new String();
 public String() {
 this.offset = 0;
 this.count = 0;
 this.value = new char[0];
 }
 //这个构造方法能解答你的疑问
 //大概得看: String(String original) 把你传入的字符串常量对象(你的是“abc”)中的每一个字符赋值到自己的内部封装的字符数组中char[] value中  构造方法结束之后  这个常量池
 //的“abc”和你的 String s =new String("abc");的s 以及对应的堆内存都没有任何联系了
 public String(String original) {
 int size = original.count;
 char[] originalValue = original.value;
 char[] v;
 if (originalValue.length > size) {
 // The array representing the String is bigger than the new
 // String itself. Perhaps this constructor is being called
 // in order to trim the baggage, so make a copy of the array.
 int off = original.offset;
 v = Arrays.copyOfRange(originalValue, off, off+size);
 } else {
 // The array representing the String is the same
 // size as the String, so no point in making a copy.
 v = originalValue;
 }
 this.offset = 0;
 this.count = size;
 this.value = v;
 }
 
 结论:
 所以  String s ="abc";  字符串引用变量在栈内存中   "abc"这个字符串常量在方法区的常量池里面
 String s =new String("abc");如果你的常量池里面实现没有“abc”  现在方法区的常量池里面构建这个"abc"
 然后这个"abc"的引用传给String类的构造方法 public String(String original)   代码你也看到了  就是把"abc"中的字符存到自己封装的数组char[] value中
 这个对象位于堆内存中  构造完之后  和 常量池的"abc"就没有关系了
 
 |