13.1 String, StringBuilder ,StringBuffer
字符串的+, 在普通的的一条语句,编译器会自动创建StringBuilder ,然后执行append.此时的效率和StringBuilder 基本一致.但是在循环语句中,使用多条语句对字符串进行累加.则每次操作都会创建一个StringBuffer对象,这样会增加创建对象的开销.
StringBuilder 是一种可变字符,但是不支持线程同步操作.
StringBuffer 是线程同步的在所有的写方法加了synchronized锁.其他的之外StringBuilder 的基本一致,最终的一些操作都是调用基类AbstractStringBuilder的操作,
对StringBuilder, StringBuffer的append方法解读:
1.StringBuilder ,StringBuffer 的append 方法列表:
2.append 可以添加null对象,并且会把他当做”null”字符串,所以这里需要注意.
在append(boolean )--->最终会添加 ”ture” 或者”false”.
image.png
append(char char) :直接在value 后面添加一个char
@Override
public AbstractStringBuilder append(char c) {
ensureCapacityInternal(count + 1);
value[count++] = c;
return this;
}
appeand(char[] str)
public AbstractStringBuilder append(char[] str) {
int len = str.length;
ensureCapacityInternal(count + len);
System.arraycopy(str, 0, value, count, len);
count += len;
return this;
}
append(String str)
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;
}
[Android sdk] str.getChars 是String 类的一个copy到字符字符数组中, 最终调用的getCharNoCheck是一个本地方法
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
...
getCharsNoCheck(srcBegin, srcEnd, dst, dstBegin);
}
[标准java openjdk1.8]
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
}
查看java openjdk 源码openjdk/jdk/src/share/native/java/lang/System.c: 可以找到对应的native代码:
/* Only register the performance-critical methods */
static JNINativeMethod methods[] = {
{"currentTimeMillis", "()J", (void *)&JVM_CurrentTimeMillis},
{"nanoTime", "()J", (void *)&JVM_NanoTime},
{"arraycopy", "(" OBJ "I" OBJ "II)V", (void *)&JVM_ArrayCopy},
};
查询到 JVM_ArrayCopy函数,在openjdk/hotspot/src/share/vm/prims/jvm.cpp
JVM_ENTRY(void, JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject src, jint src_pos,
jobject dst, jint dst_pos, jint length))
...
s->klass()->copy_array(s, src_pos, d, dst_pos, length, thread);
JVM_END
最终到达java 虚拟机的底层操作系统,进行memcpy()内存级别的字符拷贝.
13.3 无意识的递归
在对象的toString() 中不要进行类似写法:
public void toString(){
System.out.println(“xxx”+this+"dddd") ;
}
因为在进行操作符重载的过程中,发现 前面的是字符串,而this 是对象,会进行自动的调用 toString,而这时候.toString形成了无线递归操作.正确的做法是调用 super.toString();
网友评论