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