String:每次创建一个对象,字符串是不可变的
String a = new String("asd");
源码
/**
* Initializes a newly 【初始化一个新创建的】created {@code String} object so that it represents
* the same sequence of characters as the argument; in other words, the
* newly created string is a copy of the argument string. Unless an
* explicit copy of {@code original} is needed, use of this constructor is
* unnecessary since Strings are immutable.
初始化一个新创建的 {@code String} 对象,使其代表与参数相同的字符序列;换句话说,
新创建的字符串是参数字符串的副本。除非需要 {@code original} 的显式副本,
否则不需要使用此构造函数,因为字符串是不可变的
*
* @param original
* A {@code String}
*/
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
-----------------------------------------------------------------------------
StringBuffer:构造一个字符串缓冲区,其中没有字符,初始容量为 16 个字符(不需要重新创建对象,减少内存的使用)
源码:
/**
* A cache of the last value returned by toString. Cleared
* whenever the StringBuffer is modified.
toString 返回的最后一个值的缓存。每当修改 StringBuffer 时清除
*/
private transient char[] toStringCache;
/** use serialVersionUID from JDK 1.0.2 for interoperability */
static final long serialVersionUID = 3388685877147921107L;
/**
* Constructs a string buffer with no characters in it and an
* initial capacity of 16 characters.
构造一个字符串缓冲区,其中没有字符,初始容量为 16 个字符
*/
public StringBuffer() {
super(16);
}
因为stringbuffer继承了父类AbstractStringBuilder
super(16)所以StringBuffer默认为创建16长度的数组
abstract class AbstractStringBuilder implements Appendable, CharSequence {
/**
* The value is used for character storage.
*/
char[] value;
/**
* The count is the number of characters used.
*/
int count;
/**
* This no-arg constructor is necessary for serialization of subclasses.
*/
AbstractStringBuilder() {
}
/**
* Creates an AbstractStringBuilder of the specified capacity.
创建一个容量为capacity的数组
*/
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
例如:
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("s");
StringBuffer含有 synchronized,所以是线程安全的
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
/**
* Appends the specified string to this character sequence.
将指定的字符串附加到此字符序列
* <p>
* The characters of the {@code String} argument are appended, in
* order, increasing the length of this sequence by the length of the
* argument. If {@code str} is {@code null}, then the four
* characters {@code "null"} are appended.
* <p>
* Let <i>n</i> be the length of this character sequence just prior to
* execution of the {@code append} method. Then the character at
* index <i>k</i> in the new character sequence is equal to the character
* at index <i>k</i> in the old character sequence, if <i>k</i> is less
* than <i>n</i>; otherwise, it is equal to the character at index
* <i>k-n</i> in the argument {@code str}.
*
* @param str a string.
* @return a reference to this object.
*/
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;
}
=====================================
/**
* The count is the number of characters used.
计数是使用的字符数
*/
int count;
ensureCapacityInternal(count+len),将需要append的字符串长度往下传
/**
* For positive values of {@code minimumCapacity}, this method
* behaves like {@code ensureCapacity}, however it is never
* synchronized.
* If {@code minimumCapacity} is non positive due to numeric
* overflow, this method throws {@code OutOfMemoryError}.
对于 {@code minimumCapacity} 的正值,此方法的行为类似于 {@code ensureCapacity},
但它永远不会同步。 如果 {@code minimumCapacity} 由于数字溢出而为非正数,
则此方法抛出 {@code OutOfMemoryError}
*/
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0) {
value = Arrays.copyOf(value,
newCapacity(minimumCapacity));
}
}
ensureCapacityInternal(int minimumCapacity 【append的字符传长度】),因为StringBuffer默认为16长度,所以比较append传来的字符串长度是否>16,若大于则调用newCapacity(minimumCapacity)方法
/**
* Returns a capacity at least as large as the given minimum capacity.
* Returns the current capacity increased by the same amount + 2 if
* that suffices.
* Will not return a capacity greater than {@code MAX_ARRAY_SIZE}
* unless the given minimum capacity is greater than that.
返回至少与给定最小容量一样大的容量。返回当前容量增加相同的数量 + 2 如果就足够了。不会返回大于 {@code MAX_ARRAY_SIZE} 的容量除非给定的最小容量大于此值。
*
* @param minCapacity the desired minimum capacity
* @throws OutOfMemoryError if minCapacity is less than zero or
* greater than Integer.MAX_VALUE
*/
private int newCapacity(int minCapacity) {
// overflow-conscious code
int newCapacity = (value.length << 1) + 2;
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
? hugeCapacity(minCapacity)
: newCapacity;
}
意思就是如果append的字符串大于16个字符,则将初始化的16容量进行变换
(16>> 1)+2 = 32 +2 = 34容量
/**
* The maximum size of array to allocate (unless necessary).
* Some VMs reserve some header words in an array.
* Attempts to allocate larger arrays may result in
* OutOfMemoryError: Requested array size exceeds VM limit
要分配的数组的最大大小(除非必要)。一些虚拟机在数组中保留了一些头字。
尝试分配更大的数组可能会导致OutOfMemoryError: 请求的数组大小超过 VM 限制
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
------------------------
/**
* A constant holding the maximum value an {@code int} can
* have, 2<sup>31</sup>-1.
一个保持 {@code int} 可以拥有的最大值的常量,也就是2147483648
*/
@Native public static final int MAX_VALUE = 0x7fffffff;
如果append的大小比 2147483648还要大,直接抛出oom,否则赋予相应的数值