下面的语句 ,在main方法执行,创建了几个对象? 答案是4个 为什么? 我们一起来分析 1. String a = "hello"; 2. String b = "haha"; 3.String c = a+ b;
语句1. 在执行时由于并不是new出来的, 所以该字符是存放到,内存的方法区常量池内的
语句2. 同理
这两个语句执行完 ,在内存中是这样的(这里画图虽然不严谨,但是创建对象的流程是不会变的)
语句3. 我们通过 Debug 来查看源码
3.1 来到 StringBuilder类执行了他的无参构造器 但是他调用的他的父类无参构造器
public StringBuilder() { super(16); }
3.2 来到其父类 AbstractStringBuilder 的有参构造器 创建了一个长度是16的char[],并赋给value
AbstractStringBuilder(int capacity) { value = new char[capacity]; }
3.3 现在返回,回到了语句3
注意!!!: 这里返回后就已经在,堆空间创建了一个StringBuilder对象了,里面有个长度是16的value数组
String c = a+ b;
3.4 我们再次 Strp into 追进去 ,来到StringBuilder的append方法,然后它调用了父类的append方法 ,将str传了进去
现在的 str是: "hello"
public StringBuilder append(String str) { super.append(str); return this; }
3.5 我们来到父类append方法 此方法 ,最主要就是将"hello"放到 value数组内
所以现在 value数组的下标 0,1,2,3,4分别是 'h' , 'e' , ' l' , 'l' , 'o'
public AbstractStringBuilder append(String str) { if (str == null) return appendNull(); int len = str.length(); ensureCapacityInternal(count + len); str.getChars(0, len, value, count); count += len; return this; }
3.6 现在返回到了3.4(也就是StringBuilder的append方法)
注意!!!:这时候 'hello"已经存在value数组内了
public StringBuilder append(String str) { super.append(str); return this; }
3.7 回到了 ,现在a 执行完毕,现在该执行b了
String c = a+ b;
3.8 b的添加步骤和a是一样的
(1)现在str是:"haha"
public StringBuilder append(String str) { super.append(str); return this; }
(2)将 "haha"放到value数组内"hello"后面
所以现在 value数组的下标 0,1,2,3,4,5,6,7
分别是 'h' , 'e' , ' l' , 'l' , 'o' , 'h' , 'a' , 'h' , 'a'
public AbstractStringBuilder append(String str) { if (str == null) return appendNull(); int len = str.length(); ensureCapacityInternal(count + len); str.getChars(0, len, value, count); count += len; return this; }
(3) 返回到子类的append方法
注意!!!:这时候 'hellohaha"已经存在value数组内了
public StringBuilder append(String str) { super.append(str); return this; }
3.9 返回到main方法
String c = a+ b;
4.0 调用String 的toString方法
注意: 这里new了一个String对象 就是"hellohaha"
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
4.1 返回到main方法 ,让c指向StringBuilder对象
String c = a+ b;
到此语句3 就执行完了
我是一条分隔符+++++++++++++++++++++++++++++
执行到了现在 jvm的内存是这样的(这里画图虽然不严谨,但是创建对象的流程是不会变的)
所以:最终的对象有4个 ,堆中 1个,常量池3个
总结:StringBuilder sb = new StringBuilder() ; sb.append(a); sb.append(b); sb是在堆中的,并且append()是在原来字符串基础上追加的。
重要规则 :
String c1 = "ab" + "cd"; 常量相加看常量池 ,也就是c1最终指向的是常量池的地址
(这里只会创建一个String对象,就是"abcd") 就像这样
String c2 = a+b; 变量相加 c2最终是指向堆空间的
(这个已经在上面讲过了哦 就是; "hellohaha"这个例子,可以看倒数第二张图)
如果看了觉得有收获,请点个赞,发表个评论吧