JDK源码之String,StringBuffer,StringBuilder
Posted 架构探索
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDK源码之String,StringBuffer,StringBuilder相关的知识,希望对你有一定的参考价值。
前言
最近公司招聘Java开发人员,面试时会问一些jdk源码相关的问题,如String相关,但很少有答得全面的,今天总结一下,供学习参考
String,StringBuffer,StringBuilder之间的对比:
总结:
三者的继承结构(这里忽略了Serializable)
StringBuffer与StringBuilder两者之间的主要区别
(1)线程安全性,StringBuffer是线程安全的,而StringBuilder是线程非安全的,也因此在速度上, StringBuilder优于StringBuffer
(2)还有一点,StringBuffer内部有针对toString()的cache, 字段名toStringCache,StringBuffer每次操作都会将toStringCache设置为null
性能,速度
大多数情况下:StringBuilder > StringBuffer > String
单字符串操作时, String最佳, 如下:
String s1 = "abc";
StringBuilder s2 = new StringBuilder().append("abc");
使用哪一个
有大量字符串拼接或修改时, 单线程环境下用StringBuilder, 多线程环境下用StringBuffer, 若使用String进行大量字符拼接操作, 则会产生大量垃圾对象,浪费系统资源并且会影响系统性能
不涉及字符拼接以及更改时,直接使用String最佳
源码赏析:
StringBuffer与StringBuilder序列化的实现
StringBuffer的实现:
private synchronized void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
java.io.ObjectOutputStream.PutField fields = s.putFields();
fields.put("value", value);
fields.put("count", count);
fields.put("shared", false);
s.writeFields();
}
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
java.io.ObjectInputStream.GetField fields = s.readFields();
value = (char[])fields.get("value", null);
count = fields.get("count", 0);
}
StringBuilder的实现:
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
s.defaultWriteObject();
s.writeInt(count);
s.writeObject(value);
}
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();
count = s.readInt();
value = (char[]) s.readObject();
}
StringBuffer与StringBuilder的扩容检测及实现
AbstractStringBuilder类中的方法
//扩容检测
private void ensureCapacityInternal(int minimumCapacity) {
//数组长度不够容纳新元素时,进行扩容
if (minimumCapacity - value.length > 0)
expandCapacity(minimumCapacity);
}
//扩容实现
void expandCapacity(int minimumCapacity) {
int newCapacity = value.length * 2 + 2;
if (newCapacity - minimumCapacity < 0)
newCapacity = minimumCapacity;
if (newCapacity < 0) {
if (minimumCapacity < 0) // overflow
throw new OutOfMemoryError();
newCapacity = Integer.MAX_VALUE;
}
//开辟一个新数组, 并且原数组的元素复制过去
value = Arrays.copyOf(value, newCapacity);
}
String类重写的hashCode方法实现
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
以上是关于JDK源码之String,StringBuffer,StringBuilder的主要内容,如果未能解决你的问题,请参考以下文章
JDK 1.8 源码解析 StringStringBuilder和StringBuffer的异同
jdk 源码系列之StringBuilderStringBuffer