1 /* 2 * Copyright (c) 1994, 2013, 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 26 package java.lang; 27 28 import java.util.Arrays; 29 30 /** 31 * A thread-safe, mutable sequence of characters. 32 * A string buffer is like a {@link String}, but can be modified. At any 33 * point in time it contains some particular sequence of characters, but 34 * the length and content of the sequence can be changed through certain 35 * method calls. 36 * <p> 37 * String buffers are safe for use by multiple threads. The methods 38 * are synchronized where necessary so that all the operations on any 39 * particular instance behave as if they occur in some serial order 40 * that is consistent with the order of the method calls made by each of 41 * the individual threads involved. 42 * <p> 43 * The principal operations on a {@code StringBuffer} are the 44 * {@code append} and {@code insert} methods, which are 45 * overloaded so as to accept data of any type. Each effectively 46 * converts a given datum to a string and then appends or inserts the 47 * characters of that string to the string buffer. The 48 * {@code append} method always adds these characters at the end 49 * of the buffer; the {@code insert} method adds the characters at 50 * a specified point. 51 * <p> 52 * For example, if {@code z} refers to a string buffer object 53 * whose current contents are {@code "start"}, then 54 * the method call {@code z.append("le")} would cause the string 55 * buffer to contain {@code "startle"}, whereas 56 * {@code z.insert(4, "le")} would alter the string buffer to 57 * contain {@code "starlet"}. 58 * <p> 59 * In general, if sb refers to an instance of a {@code StringBuffer}, 60 * then {@code sb.append(x)} has the same effect as 61 * {@code sb.insert(sb.length(), x)}. 62 * <p> 63 * Whenever an operation occurs involving a source sequence (such as 64 * appending or inserting from a source sequence), this class synchronizes 65 * only on the string buffer performing the operation, not on the source. 66 * Note that while {@code StringBuffer} is designed to be safe to use 67 * concurrently from multiple threads, if the constructor or the 68 * {@code append} or {@code insert} operation is passed a source sequence 69 * that is shared across threads, the calling code must ensure 70 * that the operation has a consistent and unchanging view of the source 71 * sequence for the duration of the operation. 72 * This could be satisfied by the caller holding a lock during the 73 * operation's call, by using an immutable source sequence, or by not 74 * sharing the source sequence across threads. 75 * <p> 76 * Every string buffer has a capacity. As long as the length of the 77 * character sequence contained in the string buffer does not exceed 78 * the capacity, it is not necessary to allocate a new internal 79 * buffer array. If the internal buffer overflows, it is 80 * automatically made larger. 81 * <p> 82 * Unless otherwise noted, passing a {@code null} argument to a constructor 83 * or method in this class will cause a {@link NullPointerException} to be 84 * thrown. 85 * <p> 86 * As of release JDK 5, this class has been supplemented with an equivalent 87 * class designed for use by a single thread, {@link StringBuilder}. The 88 * {@code StringBuilder} class should generally be used in preference to 89 * this one, as it supports all of the same operations but it is faster, as 90 * it performs no synchronization. 91 * 92 * @author Arthur van Hoff 93 * @see java.lang.StringBuilder 94 * @see java.lang.String 95 * @since JDK1.0 96 */ 97 public final class StringBuffer 98 extends AbstractStringBuilder 99 implements java.io.Serializable, CharSequence 100 { 101 102 /** 103 * A cache of the last value returned by toString. Cleared 104 * whenever the StringBuffer is modified. 105 */ 106 private transient char[] toStringCache; 107 108 /** use serialVersionUID from JDK 1.0.2 for interoperability */ 109 static final long serialVersionUID = 3388685877147921107L; 110 111 /** 112 * Constructs a string buffer with no characters in it and an 113 * initial capacity of 16 characters. 114 */ StringBuffer()115 public StringBuffer() { 116 super(16); 117 } 118 119 /** 120 * Constructs a string buffer with no characters in it and 121 * the specified initial capacity. 122 * 123 * @param capacity the initial capacity. 124 * @exception NegativeArraySizeException if the {@code capacity} 125 * argument is less than {@code 0}. 126 */ StringBuffer(int capacity)127 public StringBuffer(int capacity) { 128 super(capacity); 129 } 130 131 /** 132 * Constructs a string buffer initialized to the contents of the 133 * specified string. The initial capacity of the string buffer is 134 * {@code 16} plus the length of the string argument. 135 * 136 * @param str the initial contents of the buffer. 137 */ StringBuffer(String str)138 public StringBuffer(String str) { 139 super(str.length() + 16); 140 append(str); 141 } 142 143 /** 144 * Constructs a string buffer that contains the same characters 145 * as the specified {@code CharSequence}. The initial capacity of 146 * the string buffer is {@code 16} plus the length of the 147 * {@code CharSequence} argument. 148 * <p> 149 * If the length of the specified {@code CharSequence} is 150 * less than or equal to zero, then an empty buffer of capacity 151 * {@code 16} is returned. 152 * 153 * @param seq the sequence to copy. 154 * @since 1.5 155 */ StringBuffer(CharSequence seq)156 public StringBuffer(CharSequence seq) { 157 this(seq.length() + 16); 158 append(seq); 159 } 160 161 @Override length()162 public synchronized int length() { 163 return count; 164 } 165 166 @Override capacity()167 public synchronized int capacity() { 168 return value.length; 169 } 170 171 172 @Override ensureCapacity(int minimumCapacity)173 public synchronized void ensureCapacity(int minimumCapacity) { 174 super.ensureCapacity(minimumCapacity); 175 } 176 177 /** 178 * @since 1.5 179 */ 180 @Override trimToSize()181 public synchronized void trimToSize() { 182 super.trimToSize(); 183 } 184 185 /** 186 * @throws IndexOutOfBoundsException {@inheritDoc} 187 * @see #length() 188 */ 189 @Override setLength(int newLength)190 public synchronized void setLength(int newLength) { 191 toStringCache = null; 192 super.setLength(newLength); 193 } 194 195 /** 196 * @throws IndexOutOfBoundsException {@inheritDoc} 197 * @see #length() 198 */ 199 @Override charAt(int index)200 public synchronized char charAt(int index) { 201 if ((index < 0) || (index >= count)) 202 throw new StringIndexOutOfBoundsException(index); 203 return value[index]; 204 } 205 206 /** 207 * @since 1.5 208 */ 209 @Override codePointAt(int index)210 public synchronized int codePointAt(int index) { 211 return super.codePointAt(index); 212 } 213 214 /** 215 * @since 1.5 216 */ 217 @Override codePointBefore(int index)218 public synchronized int codePointBefore(int index) { 219 return super.codePointBefore(index); 220 } 221 222 /** 223 * @since 1.5 224 */ 225 @Override codePointCount(int beginIndex, int endIndex)226 public synchronized int codePointCount(int beginIndex, int endIndex) { 227 return super.codePointCount(beginIndex, endIndex); 228 } 229 230 /** 231 * @since 1.5 232 */ 233 @Override offsetByCodePoints(int index, int codePointOffset)234 public synchronized int offsetByCodePoints(int index, int codePointOffset) { 235 return super.offsetByCodePoints(index, codePointOffset); 236 } 237 238 /** 239 * @throws IndexOutOfBoundsException {@inheritDoc} 240 */ 241 @Override getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)242 public synchronized void getChars(int srcBegin, int srcEnd, char[] dst, 243 int dstBegin) 244 { 245 super.getChars(srcBegin, srcEnd, dst, dstBegin); 246 } 247 248 /** 249 * @throws IndexOutOfBoundsException {@inheritDoc} 250 * @see #length() 251 */ 252 @Override setCharAt(int index, char ch)253 public synchronized void setCharAt(int index, char ch) { 254 if ((index < 0) || (index >= count)) 255 throw new StringIndexOutOfBoundsException(index); 256 toStringCache = null; 257 value[index] = ch; 258 } 259 260 @Override append(Object obj)261 public synchronized StringBuffer append(Object obj) { 262 toStringCache = null; 263 super.append(String.valueOf(obj)); 264 return this; 265 } 266 267 @Override append(String str)268 public synchronized StringBuffer append(String str) { 269 toStringCache = null; 270 super.append(str); 271 return this; 272 } 273 274 /** 275 * Appends the specified {@code StringBuffer} to this sequence. 276 * <p> 277 * The characters of the {@code StringBuffer} argument are appended, 278 * in order, to the contents of this {@code StringBuffer}, increasing the 279 * length of this {@code StringBuffer} by the length of the argument. 280 * If {@code sb} is {@code null}, then the four characters 281 * {@code "null"} are appended to this {@code StringBuffer}. 282 * <p> 283 * Let <i>n</i> be the length of the old character sequence, the one 284 * contained in the {@code StringBuffer} just prior to execution of the 285 * {@code append} method. Then the character at index <i>k</i> in 286 * the new character sequence is equal to the character at index <i>k</i> 287 * in the old character sequence, if <i>k</i> is less than <i>n</i>; 288 * otherwise, it is equal to the character at index <i>k-n</i> in the 289 * argument {@code sb}. 290 * <p> 291 * This method synchronizes on {@code this}, the destination 292 * object, but does not synchronize on the source ({@code sb}). 293 * 294 * @param sb the {@code StringBuffer} to append. 295 * @return a reference to this object. 296 * @since 1.4 297 */ append(StringBuffer sb)298 public synchronized StringBuffer append(StringBuffer sb) { 299 toStringCache = null; 300 super.append(sb); 301 return this; 302 } 303 304 /** 305 * @since 1.8 306 */ 307 @Override append(AbstractStringBuilder asb)308 synchronized StringBuffer append(AbstractStringBuilder asb) { 309 toStringCache = null; 310 super.append(asb); 311 return this; 312 } 313 314 /** 315 * Appends the specified {@code CharSequence} to this 316 * sequence. 317 * <p> 318 * The characters of the {@code CharSequence} argument are appended, 319 * in order, increasing the length of this sequence by the length of the 320 * argument. 321 * 322 * <p>The result of this method is exactly the same as if it were an 323 * invocation of this.append(s, 0, s.length()); 324 * 325 * <p>This method synchronizes on {@code this}, the destination 326 * object, but does not synchronize on the source ({@code s}). 327 * 328 * <p>If {@code s} is {@code null}, then the four characters 329 * {@code "null"} are appended. 330 * 331 * @param s the {@code CharSequence} to append. 332 * @return a reference to this object. 333 * @since 1.5 334 */ 335 @Override append(CharSequence s)336 public synchronized StringBuffer append(CharSequence s) { 337 toStringCache = null; 338 super.append(s); 339 return this; 340 } 341 342 /** 343 * @throws IndexOutOfBoundsException {@inheritDoc} 344 * @since 1.5 345 */ 346 @Override append(CharSequence s, int start, int end)347 public synchronized StringBuffer append(CharSequence s, int start, int end) 348 { 349 toStringCache = null; 350 super.append(s, start, end); 351 return this; 352 } 353 354 @Override append(char[] str)355 public synchronized StringBuffer append(char[] str) { 356 toStringCache = null; 357 super.append(str); 358 return this; 359 } 360 361 /** 362 * @throws IndexOutOfBoundsException {@inheritDoc} 363 */ 364 @Override append(char[] str, int offset, int len)365 public synchronized StringBuffer append(char[] str, int offset, int len) { 366 toStringCache = null; 367 super.append(str, offset, len); 368 return this; 369 } 370 371 @Override append(boolean b)372 public synchronized StringBuffer append(boolean b) { 373 toStringCache = null; 374 super.append(b); 375 return this; 376 } 377 378 @Override append(char c)379 public synchronized StringBuffer append(char c) { 380 toStringCache = null; 381 super.append(c); 382 return this; 383 } 384 385 @Override append(int i)386 public synchronized StringBuffer append(int i) { 387 toStringCache = null; 388 super.append(i); 389 return this; 390 } 391 392 /** 393 * @since 1.5 394 */ 395 @Override appendCodePoint(int codePoint)396 public synchronized StringBuffer appendCodePoint(int codePoint) { 397 toStringCache = null; 398 super.appendCodePoint(codePoint); 399 return this; 400 } 401 402 @Override append(long lng)403 public synchronized StringBuffer append(long lng) { 404 toStringCache = null; 405 super.append(lng); 406 return this; 407 } 408 409 @Override append(float f)410 public synchronized StringBuffer append(float f) { 411 toStringCache = null; 412 super.append(f); 413 return this; 414 } 415 416 @Override append(double d)417 public synchronized StringBuffer append(double d) { 418 toStringCache = null; 419 super.append(d); 420 return this; 421 } 422 423 /** 424 * @throws StringIndexOutOfBoundsException {@inheritDoc} 425 * @since 1.2 426 */ 427 @Override delete(int start, int end)428 public synchronized StringBuffer delete(int start, int end) { 429 toStringCache = null; 430 super.delete(start, end); 431 return this; 432 } 433 434 /** 435 * @throws StringIndexOutOfBoundsException {@inheritDoc} 436 * @since 1.2 437 */ 438 @Override deleteCharAt(int index)439 public synchronized StringBuffer deleteCharAt(int index) { 440 toStringCache = null; 441 super.deleteCharAt(index); 442 return this; 443 } 444 445 /** 446 * @throws StringIndexOutOfBoundsException {@inheritDoc} 447 * @since 1.2 448 */ 449 @Override replace(int start, int end, String str)450 public synchronized StringBuffer replace(int start, int end, String str) { 451 toStringCache = null; 452 super.replace(start, end, str); 453 return this; 454 } 455 456 /** 457 * @throws StringIndexOutOfBoundsException {@inheritDoc} 458 * @since 1.2 459 */ 460 @Override substring(int start)461 public synchronized String substring(int start) { 462 return substring(start, count); 463 } 464 465 /** 466 * @throws IndexOutOfBoundsException {@inheritDoc} 467 * @since 1.4 468 */ 469 @Override subSequence(int start, int end)470 public synchronized CharSequence subSequence(int start, int end) { 471 return super.substring(start, end); 472 } 473 474 /** 475 * @throws StringIndexOutOfBoundsException {@inheritDoc} 476 * @since 1.2 477 */ 478 @Override substring(int start, int end)479 public synchronized String substring(int start, int end) { 480 return super.substring(start, end); 481 } 482 483 /** 484 * @throws StringIndexOutOfBoundsException {@inheritDoc} 485 * @since 1.2 486 */ 487 @Override insert(int index, char[] str, int offset, int len)488 public synchronized StringBuffer insert(int index, char[] str, int offset, 489 int len) 490 { 491 toStringCache = null; 492 super.insert(index, str, offset, len); 493 return this; 494 } 495 496 /** 497 * @throws StringIndexOutOfBoundsException {@inheritDoc} 498 */ 499 @Override insert(int offset, Object obj)500 public synchronized StringBuffer insert(int offset, Object obj) { 501 toStringCache = null; 502 super.insert(offset, String.valueOf(obj)); 503 return this; 504 } 505 506 /** 507 * @throws StringIndexOutOfBoundsException {@inheritDoc} 508 */ 509 @Override insert(int offset, String str)510 public synchronized StringBuffer insert(int offset, String str) { 511 toStringCache = null; 512 super.insert(offset, str); 513 return this; 514 } 515 516 /** 517 * @throws StringIndexOutOfBoundsException {@inheritDoc} 518 */ 519 @Override insert(int offset, char[] str)520 public synchronized StringBuffer insert(int offset, char[] str) { 521 toStringCache = null; 522 super.insert(offset, str); 523 return this; 524 } 525 526 /** 527 * @throws IndexOutOfBoundsException {@inheritDoc} 528 * @since 1.5 529 */ 530 @Override insert(int dstOffset, CharSequence s)531 public StringBuffer insert(int dstOffset, CharSequence s) { 532 // Note, synchronization achieved via invocations of other StringBuffer methods 533 // after narrowing of s to specific type 534 // Ditto for toStringCache clearing 535 super.insert(dstOffset, s); 536 return this; 537 } 538 539 /** 540 * @throws IndexOutOfBoundsException {@inheritDoc} 541 * @since 1.5 542 */ 543 @Override insert(int dstOffset, CharSequence s, int start, int end)544 public synchronized StringBuffer insert(int dstOffset, CharSequence s, 545 int start, int end) 546 { 547 toStringCache = null; 548 super.insert(dstOffset, s, start, end); 549 return this; 550 } 551 552 /** 553 * @throws StringIndexOutOfBoundsException {@inheritDoc} 554 */ 555 @Override insert(int offset, boolean b)556 public StringBuffer insert(int offset, boolean b) { 557 // Note, synchronization achieved via invocation of StringBuffer insert(int, String) 558 // after conversion of b to String by super class method 559 // Ditto for toStringCache clearing 560 super.insert(offset, b); 561 return this; 562 } 563 564 /** 565 * @throws IndexOutOfBoundsException {@inheritDoc} 566 */ 567 @Override insert(int offset, char c)568 public synchronized StringBuffer insert(int offset, char c) { 569 toStringCache = null; 570 super.insert(offset, c); 571 return this; 572 } 573 574 /** 575 * @throws StringIndexOutOfBoundsException {@inheritDoc} 576 */ 577 @Override insert(int offset, int i)578 public StringBuffer insert(int offset, int i) { 579 // Note, synchronization achieved via invocation of StringBuffer insert(int, String) 580 // after conversion of i to String by super class method 581 // Ditto for toStringCache clearing 582 super.insert(offset, i); 583 return this; 584 } 585 586 /** 587 * @throws StringIndexOutOfBoundsException {@inheritDoc} 588 */ 589 @Override insert(int offset, long l)590 public StringBuffer insert(int offset, long l) { 591 // Note, synchronization achieved via invocation of StringBuffer insert(int, String) 592 // after conversion of l to String by super class method 593 // Ditto for toStringCache clearing 594 super.insert(offset, l); 595 return this; 596 } 597 598 /** 599 * @throws StringIndexOutOfBoundsException {@inheritDoc} 600 */ 601 @Override insert(int offset, float f)602 public StringBuffer insert(int offset, float f) { 603 // Note, synchronization achieved via invocation of StringBuffer insert(int, String) 604 // after conversion of f to String by super class method 605 // Ditto for toStringCache clearing 606 super.insert(offset, f); 607 return this; 608 } 609 610 /** 611 * @throws StringIndexOutOfBoundsException {@inheritDoc} 612 */ 613 @Override insert(int offset, double d)614 public StringBuffer insert(int offset, double d) { 615 // Note, synchronization achieved via invocation of StringBuffer insert(int, String) 616 // after conversion of d to String by super class method 617 // Ditto for toStringCache clearing 618 super.insert(offset, d); 619 return this; 620 } 621 622 /** 623 * @since 1.4 624 */ 625 @Override indexOf(String str)626 public int indexOf(String str) { 627 // Note, synchronization achieved via invocations of other StringBuffer methods 628 return super.indexOf(str); 629 } 630 631 /** 632 * @since 1.4 633 */ 634 @Override indexOf(String str, int fromIndex)635 public synchronized int indexOf(String str, int fromIndex) { 636 return super.indexOf(str, fromIndex); 637 } 638 639 /** 640 * @since 1.4 641 */ 642 @Override lastIndexOf(String str)643 public int lastIndexOf(String str) { 644 // Note, synchronization achieved via invocations of other StringBuffer methods 645 return lastIndexOf(str, count); 646 } 647 648 /** 649 * @since 1.4 650 */ 651 @Override lastIndexOf(String str, int fromIndex)652 public synchronized int lastIndexOf(String str, int fromIndex) { 653 return super.lastIndexOf(str, fromIndex); 654 } 655 656 /** 657 * @since JDK1.0.2 658 */ 659 @Override reverse()660 public synchronized StringBuffer reverse() { 661 toStringCache = null; 662 super.reverse(); 663 return this; 664 } 665 666 @Override toString()667 public synchronized String toString() { 668 if (toStringCache == null) { 669 toStringCache = Arrays.copyOfRange(value, 0, count); 670 } 671 return new String(toStringCache, 0, count); 672 } 673 674 /** 675 * Serializable fields for StringBuffer. 676 * 677 * @serialField value char[] 678 * The backing character array of this StringBuffer. 679 * @serialField count int 680 * The number of characters in this StringBuffer. 681 * @serialField shared boolean 682 * A flag indicating whether the backing array is shared. 683 * The value is ignored upon deserialization. 684 */ 685 private static final java.io.ObjectStreamField[] serialPersistentFields = 686 { 687 new java.io.ObjectStreamField("value", char[].class), 688 new java.io.ObjectStreamField("count", Integer.TYPE), 689 new java.io.ObjectStreamField("shared", Boolean.TYPE), 690 }; 691 692 /** 693 * readObject is called to restore the state of the StringBuffer from 694 * a stream. 695 */ writeObject(java.io.ObjectOutputStream s)696 private synchronized void writeObject(java.io.ObjectOutputStream s) 697 throws java.io.IOException { 698 java.io.ObjectOutputStream.PutField fields = s.putFields(); 699 fields.put("value", value); 700 fields.put("count", count); 701 fields.put("shared", false); 702 s.writeFields(); 703 } 704 705 /** 706 * readObject is called to restore the state of the StringBuffer from 707 * a stream. 708 */ readObject(java.io.ObjectInputStream s)709 private void readObject(java.io.ObjectInputStream s) 710 throws java.io.IOException, ClassNotFoundException { 711 java.io.ObjectInputStream.GetField fields = s.readFields(); 712 value = (char[])fields.get("value", null); 713 count = fields.get("count", 0); 714 } 715 } 716