📄 stringbuffer.java
字号:
/* * @(#)StringBuffer.java 1.72 06/10/10 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */package java.lang;import sun.misc.CVM;/** * A string buffer implements a mutable sequence of characters. * A string buffer is like a {@link String}, but can be modified. At any * point in time it contains some particular sequence of characters, but * the length and content of the sequence can be changed through certain * method calls. * <p> * String buffers are safe for use by multiple threads. The methods * are synchronized where necessary so that all the operations on any * particular instance behave as if they occur in some serial order * that is consistent with the order of the method calls made by each of * the individual threads involved. * <p> * String buffers are used by the compiler to implement the binary * string concatenation operator <code>+</code>. For example, the code: * <p><blockquote><pre> * x = "a" + 4 + "c" * </pre></blockquote><p> * is compiled to the equivalent of: * <p><blockquote><pre> * x = new StringBuffer().append("a").append(4).append("c") * .toString() * </pre></blockquote> * which creates a new string buffer (initially empty), appends the string * representation of each operand to the string buffer in turn, and then * converts the contents of the string buffer to a string. Overall, this avoids * creating many temporary strings. * <p> * The principal operations on a <code>StringBuffer</code> are the * <code>append</code> and <code>insert</code> methods, which are * overloaded so as to accept data of any type. Each effectively * converts a given datum to a string and then appends or inserts the * characters of that string to the string buffer. The * <code>append</code> method always adds these characters at the end * of the buffer; the <code>insert</code> method adds the characters at * a specified point. * <p> * For example, if <code>z</code> refers to a string buffer object * whose current contents are "<code>start</code>", then * the method call <code>z.append("le")</code> would cause the string * buffer to contain "<code>startle</code>", whereas * <code>z.insert(4, "le")</code> would alter the string buffer to * contain "<code>starlet</code>". * <p> * In general, if sb refers to an instance of a <code>StringBuffer</code>, * then <code>sb.append(x)</code> has the same effect as * <code>sb.insert(sb.length(), x)</code>. * <p> * Every string buffer has a capacity. As long as the length of the * character sequence contained in the string buffer does not exceed * the capacity, it is not necessary to allocate a new internal * buffer array. If the internal buffer overflows, it is * automatically made larger. * * @author Arthur van Hoff * @version 1.78, 05/16/03 * @see java.io.ByteArrayOutputStream * @see java.lang.String * @since JDK1.0 */ public final class StringBuffer implements java.io.Serializable, CharSequence { /** * The value is used for character storage. * * @serial */ private char value[]; /** * The count is the number of characters in the buffer. * * @serial */ private int count; /** * A flag indicating whether the buffer is shared * * @serial */ private boolean shared; /** 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. */ public StringBuffer() { this(16); } /** * Constructs a string buffer with no characters in it and an * initial capacity specified by the <code>length</code> argument. * * @param length the initial capacity. * @exception NegativeArraySizeException if the <code>length</code> * argument is less than <code>0</code>. */ public StringBuffer(int length) { value = new char[length]; shared = false; } /** * Constructs a string buffer so that it represents the same * sequence of characters as the string argument; in other * words, the initial contents of the string buffer is a copy of the * argument string. The initial capacity of the string buffer is * <code>16</code> plus the length of the string argument. * * @param str the initial contents of the buffer. * @exception NullPointerException if <code>str</code> is <code>null</code> */ public StringBuffer(String str) { this(str.length() + 16); append(str); } /** * Returns the length (character count) of this string buffer. * * @return the length of the sequence of characters currently * represented by this string buffer. */ public synchronized int length() { return count; } private int lengthSimpleSync() { if (CVM.simpleLockGrab(this)) { int result = count; CVM.simpleLockRelease(this); return result; } else { return length(); } } /* Used for quick access from java.lang.String when StringBuffer is * already sychronized. */ int lengthNoSync() { return count; } /** * Returns the current capacity of the String buffer. The capacity * is the amount of storage available for newly inserted * characters; beyond which an allocation will occur. * * @return the current capacity of this string buffer. */ public synchronized int capacity() { return value.length; } private int capacitySimpleSync() { if (CVM.simpleLockGrab(this)) { int result = value.length; CVM.simpleLockRelease(this); return result; } else { return capacity(); } } /** * Copies the buffer value. This is normally only called when shared * is true. It should only be called from a synchronized method. */ private final void copy() { char newValue[] = new char[value.length]; if(count != 0) { /* IAI - 17 */ CVM.copyCharArray(value, 0, newValue, 0, count); } value = newValue; shared = false; } /** * Ensures that the capacity of the buffer is at least equal to the * specified minimum. * If the current capacity of this string buffer is less than the * argument, then a new internal buffer is allocated with greater * capacity. The new capacity is the larger of: * <ul> * <li>The <code>minimumCapacity</code> argument. * <li>Twice the old capacity, plus <code>2</code>. * </ul> * If the <code>minimumCapacity</code> argument is nonpositive, this * method takes no action and simply returns. * * @param minimumCapacity the minimum desired capacity. */ public synchronized void ensureCapacity(int minimumCapacity) { if (minimumCapacity > value.length) { expandCapacity(minimumCapacity); } } /** * This implements the expansion semantics of ensureCapacity but is * unsynchronized for use internally by methods which are already * synchronized. * * @see java.lang.StringBuffer#ensureCapacity(int) */ private native void expandCapacity(int minimumCapacity); /* * The original Java version * * private void expandCapacity(int minimumCapacity) { * int newCapacity = (value.length + 1) * 2; * if (newCapacity < 0) { * newCapacity = Integer.MAX_VALUE; * } else if (minimumCapacity > newCapacity) { * newCapacity = minimumCapacity; * } * char newValue[] = new char[newCapacity]; * System.arraycopy(value, 0, newValue, 0, count); * value = newValue; * shared = false; * } */ /** * Sets the length of this String buffer. * This string buffer is altered to represent a new character sequence * whose length is specified by the argument. For every nonnegative * index <i>k</i> less than <code>newLength</code>, the character at * index <i>k</i> in the new character sequence is the same as the * character at index <i>k</i> in the old sequence if <i>k</i> is less * than the length of the old character sequence; otherwise, it is the * null character <code>'\u0000'</code>. * * In other words, if the <code>newLength</code> argument is less than * the current length of the string buffer, the string buffer is * truncated to contain exactly the number of characters given by the * <code>newLength</code> argument. * <p> * If the <code>newLength</code> argument is greater than or equal * to the current length, sufficient null characters * (<code>'\u0000'</code>) are appended to the string buffer so that * length becomes the <code>newLength</code> argument. * <p> * The <code>newLength</code> argument must be greater than or equal * to <code>0</code>. * * @param newLength the new length of the buffer. * @exception IndexOutOfBoundsException if the * <code>newLength</code> argument is negative. * @see java.lang.StringBuffer#length() */ public synchronized void setLength(int newLength) { if (newLength < 0) { throw new StringIndexOutOfBoundsException(newLength); } if (newLength > value.length) { expandCapacity(newLength); } if (count < newLength) { if (shared) copy(); for (; count < newLength; count++) { value[count] = '\0'; } } else { count = newLength; if (shared) { if (newLength > 0) { copy(); } else { // If newLength is zero, assume the StringBuffer is being // stripped for reuse; Make new buffer of default size value = new char[16]; shared = false; } } } } /** * The specified character of the sequence currently represented by * the string buffer, as indicated by the <code>index</code> argument, * is returned. The first character of a string buffer is at index * <code>0</code>, the next at index <code>1</code>, and so on, for * array indexing. * <p> * The index argument must be greater than or equal to * <code>0</code>, and less than the length of this string buffer. * * @param index the index of the desired character. * @return the character at the specified index of this string buffer. * @exception IndexOutOfBoundsException if <code>index</code> is * negative or greater than or equal to <code>length()</code>. * @see java.lang.StringBuffer#length() */ public synchronized char charAt(int index) { if ((index < 0) || (index >= count)) { throw new StringIndexOutOfBoundsException(index); } return value[index]; } private char charAtSimpleSync(int index) { if (CVM.simpleLockGrab(this)) { char result; boolean gotResult; if ((index >= 0) && (index < count)) { result = value[index]; gotResult = true; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -