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 public synchronized StringBuffer append(char[] str) { 323 super.append(str); 324 return this; 325 } 326 327 /** 328 * @throws IndexOutOfBoundsException {@inheritDoc} 329 */ 330 public synchronized StringBuffer append(char[] str, int offset, int len) { 331 super.append(str, offset, len); 332 return this; 333 } 334 335 public synchronized StringBuffer append(boolean b) { 336 super.append(b); 337 return this; 338 } 339 340 public synchronized StringBuffer append(char c) { 341 super.append(c); 342 return this; 343 } 344 345 public synchronized StringBuffer append(int i) { 346 super.append(i); 347 return this; 348 } 349 350 /** 351 * @since 1.5 352 */ 353 public synchronized StringBuffer appendCodePoint(int codePoint) { 354 super.appendCodePoint(codePoint); 355 return this; 356 } 357 358 public synchronized StringBuffer append(long lng) { 359 super.append(lng); 360 return this; 361 } 362 363 public synchronized StringBuffer append(float f) { 364 super.append(f); 365 return this; 366 } 367 368 public synchronized StringBuffer append(double d) { 369 super.append(d); 370 return this; 371 } 372 373 /** 374 * @throws StringIndexOutOfBoundsException {@inheritDoc} 375 * @since 1.2 376 */ 377 public synchronized StringBuffer delete(int start, int end) { 378 super.delete(start, end); 379 return this; 380 } 381 382 /** 383 * @throws StringIndexOutOfBoundsException {@inheritDoc} 384 * @since 1.2 385 */ 386 public synchronized StringBuffer deleteCharAt(int index) { 387 super.deleteCharAt(index); 388 return this; 389 } 390 391 /** 392 * @throws StringIndexOutOfBoundsException {@inheritDoc} 393 * @since 1.2 394 */ 395 public synchronized StringBuffer replace(int start, int end, String str) { 396 super.replace(start, end, str); 397 return this; 398 } 399 400 /** 401 * @throws StringIndexOutOfBoundsException {@inheritDoc} 402 * @since 1.2 403 */ 404 public synchronized String substring(int start) { 405 return substring(start, count); 406 } 407 408 /** 409 * @throws IndexOutOfBoundsException {@inheritDoc} 410 * @since 1.4 411 */ 412 public synchronized CharSequence subSequence(int start, int end) { 413 return super.substring(start, end); 414 } 415 416 /** 417 * @throws StringIndexOutOfBoundsException {@inheritDoc} 418 * @since 1.2 419 */ 420 public synchronized String substring(int start, int end) { 421 return super.substring(start, end); 422 } 423 424 /** 425 * @throws StringIndexOutOfBoundsException {@inheritDoc} 426 * @since 1.2 427 */ 428 public synchronized StringBuffer insert(int index, char[] str, int offset, 429 int len) 430 { 431 super.insert(index, str, offset, len); 432 return this; 433 } 434 435 /** 436 * @throws StringIndexOutOfBoundsException {@inheritDoc} 437 */ 438 public synchronized StringBuffer insert(int offset, Object obj) { 439 super.insert(offset, String.valueOf(obj)); 440 return this; 441 } 442 443 /** 444 * @throws StringIndexOutOfBoundsException {@inheritDoc} 445 */ 446 public synchronized StringBuffer insert(int offset, String str) { 447 super.insert(offset, str); 448 return this; 449 } 450 451 /** 452 * @throws StringIndexOutOfBoundsException {@inheritDoc} 453 */ 454 public synchronized StringBuffer insert(int offset, char[] str) { 455 super.insert(offset, str); 456 return this; 457 } 458 459 /** 460 * @throws IndexOutOfBoundsException {@inheritDoc} 461 * @since 1.5 462 */ 463 public StringBuffer insert(int dstOffset, CharSequence s) { 464 // Note, synchronization achieved via other invocations 465 if (s == null) 466 s = "null"; 467 if (s instanceof String) 468 return this.insert(dstOffset, (String)s); 469 return this.insert(dstOffset, s, 0, s.length()); 470 } 471 472 /** 473 * @throws IndexOutOfBoundsException {@inheritDoc} 474 * @since 1.5 475 */ 476 public synchronized StringBuffer insert(int dstOffset, CharSequence s, 477 int start, int end) 478 { 479 super.insert(dstOffset, s, start, end); 480 return this; 481 } 482 483 /** 484 * @throws StringIndexOutOfBoundsException {@inheritDoc} 485 */ 486 public StringBuffer insert(int offset, boolean b) { 487 return insert(offset, String.valueOf(b)); 488 } 489 490 /** 491 * @throws IndexOutOfBoundsException {@inheritDoc} 492 */ 493 public synchronized StringBuffer insert(int offset, char c) { 494 super.insert(offset, c); 495 return this; 496 } 497 498 /** 499 * @throws StringIndexOutOfBoundsException {@inheritDoc} 500 */ 501 public StringBuffer insert(int offset, int i) { 502 return insert(offset, String.valueOf(i)); 503 } 504 505 /** 506 * @throws StringIndexOutOfBoundsException {@inheritDoc} 507 */ 508 public StringBuffer insert(int offset, long l) { 509 return insert(offset, String.valueOf(l)); 510 } 511 512 /** 513 * @throws StringIndexOutOfBoundsException {@inheritDoc} 514 */ 515 public StringBuffer insert(int offset, float f) { 516 return insert(offset, String.valueOf(f)); 517 } 518 519 /** 520 * @throws StringIndexOutOfBoundsException {@inheritDoc} 521 */ 522 public StringBuffer insert(int offset, double d) { 523 return insert(offset, String.valueOf(d)); 524 } 525 526 /** 527 * @throws NullPointerException {@inheritDoc} 528 * @since 1.4 529 */ 530 public int indexOf(String str) { 531 return indexOf(str, 0); 532 } 533 534 /** 535 * @throws NullPointerException {@inheritDoc} 536 * @since 1.4 537 */ 538 public synchronized int indexOf(String str, int fromIndex) { 539 return String.indexOf(value, 0, count, 540 str.toCharArray(), 0, str.length(), fromIndex); 541 } 542 543 /** 544 * @throws NullPointerException {@inheritDoc} 545 * @since 1.4 546 */ 547 public int lastIndexOf(String str) { 548 // Note, synchronization achieved via other invocations 549 return lastIndexOf(str, count); 550 } 551 552 /** 553 * @throws NullPointerException {@inheritDoc} 554 * @since 1.4 555 */ 556 public synchronized int lastIndexOf(String str, int fromIndex) { 557 return String.lastIndexOf(value, 0, count, 558 str.toCharArray(), 0, str.length(), fromIndex); 559 } 560 561 /** 562 * @since JDK1.0.2 563 */ 564 public synchronized StringBuffer reverse() { 565 super.reverse(); 566 return this; 567 } 568 569 public synchronized String toString() { 570 return new String(value, 0, count); 571 } 572 573 /** 574 * Serializable fields for StringBuffer. 575 * 576 * @serialField value char[] 577 * The backing character array of this StringBuffer. 578 * @serialField count int 579 * The number of characters in this StringBuffer. 580 * @serialField shared boolean 581 * A flag indicating whether the backing array is shared. 582 * The value is ignored upon deserialization. 583 */ 584 private static final java.io.ObjectStreamField[] serialPersistentFields = 585 { 586 new java.io.ObjectStreamField("value", char[].class), 587 new java.io.ObjectStreamField("count", Integer.TYPE), 588 new java.io.ObjectStreamField("shared", Boolean.TYPE), 589 }; 590 591 /** 592 * readObject is called to restore the state of the StringBuffer from 593 * a stream. 594 */ 595 private synchronized void writeObject(java.io.ObjectOutputStream s) 596 throws java.io.IOException { 597 java.io.ObjectOutputStream.PutField fields = s.putFields(); 598 fields.put("value", value); 599 fields.put("count", count); 600 fields.put("shared", false); 601 s.writeFields(); 602 } 603 604 /** 605 * readObject is called to restore the state of the StringBuffer from 606 * a stream. 607 */ 608 private void readObject(java.io.ObjectInputStream s) 609 throws java.io.IOException, ClassNotFoundException { 610 java.io.ObjectInputStream.GetField fields = s.readFields(); 611 value = (char[])fields.get("value", null); 612 count = fields.get("count", 0); 613 } 614 }