1/* 2 * Copyright (c) 1994, 2008, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package java.lang; 27 28 29/** 30 * A thread-safe, mutable sequence of characters. 31 * A string buffer is like a {@link String}, but can be modified. At any 32 * point in time it contains some particular sequence of characters, but 33 * the length and content of the sequence can be changed through certain 34 * method calls. 35 * <p> 36 * String buffers are safe for use by multiple threads. The methods 37 * are synchronized where necessary so that all the operations on any 38 * particular instance behave as if they occur in some serial order 39 * that is consistent with the order of the method calls made by each of 40 * the individual threads involved. 41 * <p> 42 * The principal operations on a <code>StringBuffer</code> are the 43 * <code>append</code> and <code>insert</code> methods, which are 44 * overloaded so as to accept data of any type. Each effectively 45 * converts a given datum to a string and then appends or inserts the 46 * characters of that string to the string buffer. The 47 * <code>append</code> method always adds these characters at the end 48 * of the buffer; the <code>insert</code> method adds the characters at 49 * a specified point. 50 * <p> 51 * For example, if <code>z</code> refers to a string buffer object 52 * whose current contents are "<code>start</code>", then 53 * the method call <code>z.append("le")</code> would cause the string 54 * buffer to contain "<code>startle</code>", whereas 55 * <code>z.insert(4, "le")</code> would alter the string buffer to 56 * contain "<code>starlet</code>". 57 * <p> 58 * In general, if sb refers to an instance of a <code>StringBuffer</code>, 59 * then <code>sb.append(x)</code> has the same effect as 60 * <code>sb.insert(sb.length(), x)</code>. 61 * <p> 62 * Whenever an operation occurs involving a source sequence (such as 63 * appending or inserting from a source sequence) this class synchronizes 64 * only on the string buffer performing the operation, not on the source. 65 * <p> 66 * Every string buffer has a capacity. As long as the length of the 67 * character sequence contained in the string buffer does not exceed 68 * the capacity, it is not necessary to allocate a new internal 69 * buffer array. If the internal buffer overflows, it is 70 * automatically made larger. 71 * 72 * As of release JDK 5, this class has been supplemented with an equivalent 73 * class designed for use by a single thread, {@link StringBuilder}. The 74 * <tt>StringBuilder</tt> class should generally be used in preference to 75 * this one, as it supports all of the same operations but it is faster, as 76 * it performs no synchronization. 77 * 78 * @author Arthur van Hoff 79 * @see java.lang.StringBuilder 80 * @see java.lang.String 81 * @since JDK1.0 82 */ 83 public final class StringBuffer 84 extends AbstractStringBuilder 85 implements java.io.Serializable, Appendable, CharSequence 86{ 87 88 /** use serialVersionUID from JDK 1.0.2 for interoperability */ 89 static final long serialVersionUID = 3388685877147921107L; 90 91 /** 92 * Constructs a string buffer with no characters in it and an 93 * initial capacity of 16 characters. 94 */ 95 public StringBuffer() { 96 super(16); 97 } 98 99 /** 100 * Constructs a string buffer with no characters in it and 101 * the specified initial capacity. 102 * 103 * @param capacity the initial capacity. 104 * @exception NegativeArraySizeException if the <code>capacity</code> 105 * argument is less than <code>0</code>. 106 */ 107 public StringBuffer(int capacity) { 108 super(capacity); 109 } 110 111 /** 112 * Constructs a string buffer initialized to the contents of the 113 * specified string. The initial capacity of the string buffer is 114 * <code>16</code> plus the length of the string argument. 115 * 116 * @param str the initial contents of the buffer. 117 * @exception NullPointerException if <code>str</code> is <code>null</code> 118 */ 119 public StringBuffer(String str) { 120 super(str.length() + 16); 121 append(str); 122 } 123 124 /** 125 * Constructs a string buffer that contains the same characters 126 * as the specified <code>CharSequence</code>. The initial capacity of 127 * the string buffer is <code>16</code> plus the length of the 128 * <code>CharSequence</code> argument. 129 * <p> 130 * If the length of the specified <code>CharSequence</code> is 131 * less than or equal to zero, then an empty buffer of capacity 132 * <code>16</code> is returned. 133 * 134 * @param seq the sequence to copy. 135 * @exception NullPointerException if <code>seq</code> is <code>null</code> 136 * @since 1.5 137 */ 138 public StringBuffer(CharSequence seq) { 139 this(seq.length() + 16); 140 append(seq); 141 } 142 143 public synchronized int length() { 144 return count; 145 } 146 147 public synchronized int capacity() { 148 return value.length; 149 } 150 151 152 public synchronized void ensureCapacity(int minimumCapacity) { 153 if (minimumCapacity > value.length) { 154 expandCapacity(minimumCapacity); 155 } 156 } 157 158 /** 159 * @since 1.5 160 */ 161 public synchronized void trimToSize() { 162 super.trimToSize(); 163 } 164 165 /** 166 * @throws IndexOutOfBoundsException {@inheritDoc} 167 * @see #length() 168 */ 169 public synchronized void setLength(int newLength) { 170 super.setLength(newLength); 171 } 172 173 /** 174 * @throws IndexOutOfBoundsException {@inheritDoc} 175 * @see #length() 176 */ 177 public synchronized char charAt(int index) { 178 if ((index < 0) || (index >= count)) 179 throw new StringIndexOutOfBoundsException(index); 180 return value[index]; 181 } 182 183 /** 184 * @since 1.5 185 */ 186 public synchronized int codePointAt(int index) { 187 return super.codePointAt(index); 188 } 189 190 /** 191 * @since 1.5 192 */ 193 public synchronized int codePointBefore(int index) { 194 return super.codePointBefore(index); 195 } 196 197 /** 198 * @since 1.5 199 */ 200 public synchronized int codePointCount(int beginIndex, int endIndex) { 201 return super.codePointCount(beginIndex, endIndex); 202 } 203 204 /** 205 * @since 1.5 206 */ 207 public synchronized int offsetByCodePoints(int index, int codePointOffset) { 208 return super.offsetByCodePoints(index, codePointOffset); 209 } 210 211 /** 212 * @throws NullPointerException {@inheritDoc} 213 * @throws IndexOutOfBoundsException {@inheritDoc} 214 */ 215 public synchronized void getChars(int srcBegin, int srcEnd, char[] dst, 216 int dstBegin) 217 { 218 super.getChars(srcBegin, srcEnd, dst, dstBegin); 219 } 220 221 /** 222 * @throws IndexOutOfBoundsException {@inheritDoc} 223 * @see #length() 224 */ 225 public synchronized void setCharAt(int index, char ch) { 226 if ((index < 0) || (index >= count)) 227 throw new StringIndexOutOfBoundsException(index); 228 value[index] = ch; 229 } 230 231 public synchronized StringBuffer append(Object obj) { 232 super.append(String.valueOf(obj)); 233 return this; 234 } 235 236 public synchronized StringBuffer append(String str) { 237 super.append(str); 238 return this; 239 } 240 241 /** 242 * Appends the specified <tt>StringBuffer</tt> to this sequence. 243 * <p> 244 * The characters of the <tt>StringBuffer</tt> argument are appended, 245 * in order, to the contents of this <tt>StringBuffer</tt>, increasing the 246 * length of this <tt>StringBuffer</tt> by the length of the argument. 247 * If <tt>sb</tt> is <tt>null</tt>, then the four characters 248 * <tt>"null"</tt> are appended to this <tt>StringBuffer</tt>. 249 * <p> 250 * Let <i>n</i> be the length of the old character sequence, the one 251 * contained in the <tt>StringBuffer</tt> just prior to execution of the 252 * <tt>append</tt> method. Then the character at index <i>k</i> in 253 * the new character sequence is equal to the character at index <i>k</i> 254 * in the old character sequence, if <i>k</i> is less than <i>n</i>; 255 * otherwise, it is equal to the character at index <i>k-n</i> in the 256 * argument <code>sb</code>. 257 * <p> 258 * This method synchronizes on <code>this</code> (the destination) 259 * object but does not synchronize on the source (<code>sb</code>). 260 * 261 * @param sb the <tt>StringBuffer</tt> to append. 262 * @return a reference to this object. 263 * @since 1.4 264 */ 265 public synchronized StringBuffer append(StringBuffer sb) { 266 super.append(sb); 267 return this; 268 } 269 270 271 /** 272 * Appends the specified <code>CharSequence</code> to this 273 * sequence. 274 * <p> 275 * The characters of the <code>CharSequence</code> argument are appended, 276 * in order, increasing the length of this sequence by the length of the 277 * argument. 278 * 279 * <p>The result of this method is exactly the same as if it were an 280 * invocation of this.append(s, 0, s.length()); 281 * 282 * <p>This method synchronizes on this (the destination) 283 * object but does not synchronize on the source (<code>s</code>). 284 * 285 * <p>If <code>s</code> is <code>null</code>, then the four characters 286 * <code>"null"</code> are appended. 287 * 288 * @param s the <code>CharSequence</code> to append. 289 * @return a reference to this object. 290 * @since 1.5 291 */ 292 public StringBuffer append(CharSequence s) { 293 // Note, synchronization achieved via other invocations 294 if (s == null) 295 s = "null"; 296 if (s instanceof String) 297 return this.append((String)s); 298 if (s instanceof StringBuffer) 299 return this.append((StringBuffer)s); 300 return this.append(s, 0, s.length()); 301 } 302 303 /** 304 * @throws IndexOutOfBoundsException {@inheritDoc} 305 * @since 1.5 306 */ 307 public synchronized StringBuffer append(CharSequence s, int start, int end) 308 { 309 super.append(s, start, end); 310 return this; 311 } 312 313 public synchronized StringBuffer append(char[] str) { 314 super.append(str); 315 return this; 316 } 317 318 /** 319 * @throws IndexOutOfBoundsException {@inheritDoc} 320 */ 321 public synchronized StringBuffer append(char[] str, int offset, int len) { 322 super.append(str, offset, len); 323 return this; 324 } 325 326 public synchronized StringBuffer append(boolean b) { 327 super.append(b); 328 return this; 329 } 330 331 public synchronized StringBuffer append(char c) { 332 super.append(c); 333 return this; 334 } 335 336 public synchronized StringBuffer append(int i) { 337 super.append(i); 338 return this; 339 } 340 341 /** 342 * @since 1.5 343 */ 344 public synchronized StringBuffer appendCodePoint(int codePoint) { 345 super.appendCodePoint(codePoint); 346 return this; 347 } 348 349 public synchronized StringBuffer append(long lng) { 350 super.append(lng); 351 return this; 352 } 353 354 public synchronized StringBuffer append(float f) { 355 super.append(f); 356 return this; 357 } 358 359 public synchronized StringBuffer append(double d) { 360 super.append(d); 361 return this; 362 } 363 364 /** 365 * @throws StringIndexOutOfBoundsException {@inheritDoc} 366 * @since 1.2 367 */ 368 public synchronized StringBuffer delete(int start, int end) { 369 super.delete(start, end); 370 return this; 371 } 372 373 /** 374 * @throws StringIndexOutOfBoundsException {@inheritDoc} 375 * @since 1.2 376 */ 377 public synchronized StringBuffer deleteCharAt(int index) { 378 super.deleteCharAt(index); 379 return this; 380 } 381 382 /** 383 * @throws StringIndexOutOfBoundsException {@inheritDoc} 384 * @since 1.2 385 */ 386 public synchronized StringBuffer replace(int start, int end, String str) { 387 super.replace(start, end, str); 388 return this; 389 } 390 391 /** 392 * @throws StringIndexOutOfBoundsException {@inheritDoc} 393 * @since 1.2 394 */ 395 public synchronized String substring(int start) { 396 return substring(start, count); 397 } 398 399 /** 400 * @throws IndexOutOfBoundsException {@inheritDoc} 401 * @since 1.4 402 */ 403 public synchronized CharSequence subSequence(int start, int end) { 404 return super.substring(start, end); 405 } 406 407 /** 408 * @throws StringIndexOutOfBoundsException {@inheritDoc} 409 * @since 1.2 410 */ 411 public synchronized String substring(int start, int end) { 412 return super.substring(start, end); 413 } 414 415 /** 416 * @throws StringIndexOutOfBoundsException {@inheritDoc} 417 * @since 1.2 418 */ 419 public synchronized StringBuffer insert(int index, char[] str, int offset, 420 int len) 421 { 422 super.insert(index, str, offset, len); 423 return this; 424 } 425 426 /** 427 * @throws StringIndexOutOfBoundsException {@inheritDoc} 428 */ 429 public synchronized StringBuffer insert(int offset, Object obj) { 430 super.insert(offset, String.valueOf(obj)); 431 return this; 432 } 433 434 /** 435 * @throws StringIndexOutOfBoundsException {@inheritDoc} 436 */ 437 public synchronized StringBuffer insert(int offset, String str) { 438 super.insert(offset, str); 439 return this; 440 } 441 442 /** 443 * @throws StringIndexOutOfBoundsException {@inheritDoc} 444 */ 445 public synchronized StringBuffer insert(int offset, char[] str) { 446 super.insert(offset, str); 447 return this; 448 } 449 450 /** 451 * @throws IndexOutOfBoundsException {@inheritDoc} 452 * @since 1.5 453 */ 454 public StringBuffer insert(int dstOffset, CharSequence s) { 455 // Note, synchronization achieved via other invocations 456 if (s == null) 457 s = "null"; 458 if (s instanceof String) 459 return this.insert(dstOffset, (String)s); 460 return this.insert(dstOffset, s, 0, s.length()); 461 } 462 463 /** 464 * @throws IndexOutOfBoundsException {@inheritDoc} 465 * @since 1.5 466 */ 467 public synchronized StringBuffer insert(int dstOffset, CharSequence s, 468 int start, int end) 469 { 470 super.insert(dstOffset, s, start, end); 471 return this; 472 } 473 474 /** 475 * @throws StringIndexOutOfBoundsException {@inheritDoc} 476 */ 477 public StringBuffer insert(int offset, boolean b) { 478 return insert(offset, String.valueOf(b)); 479 } 480 481 /** 482 * @throws IndexOutOfBoundsException {@inheritDoc} 483 */ 484 public synchronized StringBuffer insert(int offset, char c) { 485 super.insert(offset, c); 486 return this; 487 } 488 489 /** 490 * @throws StringIndexOutOfBoundsException {@inheritDoc} 491 */ 492 public StringBuffer insert(int offset, int i) { 493 return insert(offset, String.valueOf(i)); 494 } 495 496 /** 497 * @throws StringIndexOutOfBoundsException {@inheritDoc} 498 */ 499 public StringBuffer insert(int offset, long l) { 500 return insert(offset, String.valueOf(l)); 501 } 502 503 /** 504 * @throws StringIndexOutOfBoundsException {@inheritDoc} 505 */ 506 public StringBuffer insert(int offset, float f) { 507 return insert(offset, String.valueOf(f)); 508 } 509 510 /** 511 * @throws StringIndexOutOfBoundsException {@inheritDoc} 512 */ 513 public StringBuffer insert(int offset, double d) { 514 return insert(offset, String.valueOf(d)); 515 } 516 517 /** 518 * @throws NullPointerException {@inheritDoc} 519 * @since 1.4 520 */ 521 public int indexOf(String str) { 522 return indexOf(str, 0); 523 } 524 525 /** 526 * @throws NullPointerException {@inheritDoc} 527 * @since 1.4 528 */ 529 public synchronized int indexOf(String str, int fromIndex) { 530 return String.indexOf(value, 0, count, 531 str.toCharArray(), 0, str.length(), fromIndex); 532 } 533 534 /** 535 * @throws NullPointerException {@inheritDoc} 536 * @since 1.4 537 */ 538 public int lastIndexOf(String str) { 539 // Note, synchronization achieved via other invocations 540 return lastIndexOf(str, count); 541 } 542 543 /** 544 * @throws NullPointerException {@inheritDoc} 545 * @since 1.4 546 */ 547 public synchronized int lastIndexOf(String str, int fromIndex) { 548 return String.lastIndexOf(value, 0, count, 549 str.toCharArray(), 0, str.length(), fromIndex); 550 } 551 552 /** 553 * @since JDK1.0.2 554 */ 555 public synchronized StringBuffer reverse() { 556 super.reverse(); 557 return this; 558 } 559 560 public synchronized String toString() { 561 return new String(value, 0, count); 562 } 563 564 /** 565 * Serializable fields for StringBuffer. 566 * 567 * @serialField value char[] 568 * The backing character array of this StringBuffer. 569 * @serialField count int 570 * The number of characters in this StringBuffer. 571 * @serialField shared boolean 572 * A flag indicating whether the backing array is shared. 573 * The value is ignored upon deserialization. 574 */ 575 private static final java.io.ObjectStreamField[] serialPersistentFields = 576 { 577 new java.io.ObjectStreamField("value", char[].class), 578 new java.io.ObjectStreamField("count", Integer.TYPE), 579 new java.io.ObjectStreamField("shared", Boolean.TYPE), 580 }; 581 582 /** 583 * readObject is called to restore the state of the StringBuffer from 584 * a stream. 585 */ 586 private synchronized void writeObject(java.io.ObjectOutputStream s) 587 throws java.io.IOException { 588 java.io.ObjectOutputStream.PutField fields = s.putFields(); 589 fields.put("value", value); 590 fields.put("count", count); 591 fields.put("shared", false); 592 s.writeFields(); 593 } 594 595 /** 596 * readObject is called to restore the state of the StringBuffer from 597 * a stream. 598 */ 599 private void readObject(java.io.ObjectInputStream s) 600 throws java.io.IOException, ClassNotFoundException { 601 java.io.ObjectInputStream.GetField fields = s.readFields(); 602 value = (char[])fields.get("value", null); 603 count = fields.get("count", 0); 604 } 605} 606