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