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 mutable sequence of characters. This class provides an API compatible 31 * with {@code StringBuffer}, but with no guarantee of synchronization. 32 * This class is designed for use as a drop-in replacement for 33 * {@code StringBuffer} in places where the string buffer was being 34 * used by a single thread (as is generally the case). Where possible, 35 * it is recommended that this class be used in preference to 36 * {@code StringBuffer} as it will be faster under most implementations. 37 * 38 * <p>The principal operations on a {@code StringBuilder} are the 39 * {@code append} and {@code insert} methods, which are 40 * overloaded so as to accept data of any type. Each effectively 41 * converts a given datum to a string and then appends or inserts the 42 * characters of that string to the string builder. The 43 * {@code append} method always adds these characters at the end 44 * of the builder; the {@code insert} method adds the characters at 45 * a specified point. 46 * <p> 47 * For example, if {@code z} refers to a string builder object 48 * whose current contents are "{@code start}", then 49 * the method call {@code z.append("le")} would cause the string 50 * builder to contain "{@code startle}", whereas 51 * {@code z.insert(4, "le")} would alter the string builder to 52 * contain "{@code starlet}". 53 * <p> 54 * In general, if sb refers to an instance of a {@code StringBuilder}, 55 * then {@code sb.append(x)} has the same effect as 56 * {@code sb.insert(sb.length(), x)}. 57 * <p> 58 * Every string builder has a capacity. As long as the length of the 59 * character sequence contained in the string builder does not exceed 60 * the capacity, it is not necessary to allocate a new internal 61 * buffer. If the internal buffer overflows, it is automatically made larger. 62 * 63 * <p>Instances of {@code StringBuilder} are not safe for 64 * use by multiple threads. If such synchronization is required then it is 65 * recommended that {@link java.lang.StringBuffer} be used. 66 * 67 * <p>Unless otherwise noted, passing a {@code null} argument to a constructor 68 * or method in this class will cause a {@link NullPointerException} to be 69 * thrown. 70 * 71 * @author Michael McCloskey 72 * @see java.lang.StringBuffer 73 * @see java.lang.String 74 * @since 1.5 75 */ 76 public final class StringBuilder 77 extends AbstractStringBuilder 78 implements java.io.Serializable, CharSequence 79 { 80 81 /** use serialVersionUID for interoperability */ 82 static final long serialVersionUID = 4383685877147921099L; 83 84 /** 85 * Constructs a string builder with no characters in it and an 86 * initial capacity of 16 characters. 87 */ 88 public StringBuilder() { 89 super(16); 90 } 91 92 /** 93 * Constructs a string builder with no characters in it and an 94 * initial capacity specified by the {@code capacity} argument. 95 * 96 * @param capacity the initial capacity. 97 * @throws NegativeArraySizeException if the {@code capacity} 98 * argument is less than {@code 0}. 99 */ 100 public StringBuilder(int capacity) { 101 super(capacity); 102 } 103 104 /** 105 * Constructs a string builder initialized to the contents of the 106 * specified string. The initial capacity of the string builder is 107 * {@code 16} plus the length of the string argument. 108 * 109 * @param str the initial contents of the buffer. 110 */ 111 public StringBuilder(String str) { 112 super(str.length() + 16); 113 append(str); 114 } 115 116 /** 117 * Constructs a string builder that contains the same characters 118 * as the specified {@code CharSequence}. The initial capacity of 119 * the string builder is {@code 16} plus the length of the 120 * {@code CharSequence} argument. 121 * 122 * @param seq the sequence to copy. 123 */ 124 public StringBuilder(CharSequence seq) { 125 this(seq.length() + 16); 126 append(seq); 127 } 128 129 @Override 130 public StringBuilder append(Object obj) { 131 return append(String.valueOf(obj)); 132 } 133 134 @Override 135 public StringBuilder append(String str) { 136 super.append(str); 137 return this; 138 } 139 140 /** 141 * Appends the specified {@code StringBuffer} to this sequence. 142 * <p> 143 * The characters of the {@code StringBuffer} argument are appended, 144 * in order, to this sequence, increasing the 145 * length of this sequence by the length of the argument. 146 * If {@code sb} is {@code null}, then the four characters 147 * {@code "null"} are appended to this sequence. 148 * <p> 149 * Let <i>n</i> be the length of this character sequence just prior to 150 * execution of the {@code append} method. Then the character at index 151 * <i>k</i> in the new character sequence is equal to the character at 152 * index <i>k</i> in the old character sequence, if <i>k</i> is less than 153 * <i>n</i>; otherwise, it is equal to the character at index <i>k-n</i> 154 * in the argument {@code sb}. 155 * 156 * @param sb the {@code StringBuffer} to append. 157 * @return a reference to this object. 158 */ 159 public StringBuilder append(StringBuffer sb) { 160 super.append(sb); 161 return this; 162 } 163 164 @Override 165 public StringBuilder append(CharSequence s) { 166 super.append(s); 167 return this; 168 } 169 170 /** 171 * @throws IndexOutOfBoundsException {@inheritDoc} 172 */ 173 @Override 174 public StringBuilder append(CharSequence s, int start, int end) { 175 super.append(s, start, end); 176 return this; 177 } 178 179 @Override 180 public StringBuilder append(char[] str) { 181 super.append(str); 182 return this; 183 } 184 185 /** 186 * @throws IndexOutOfBoundsException {@inheritDoc} 187 */ 188 @Override 189 public StringBuilder append(char[] str, int offset, int len) { 190 super.append(str, offset, len); 191 return this; 192 } 193 194 @Override 195 public StringBuilder append(boolean b) { 196 super.append(b); 197 return this; 198 } 199 200 @Override 201 public StringBuilder append(char c) { 202 super.append(c); 203 return this; 204 } 205 206 @Override 207 public StringBuilder append(int i) { 208 super.append(i); 209 return this; 210 } 211 212 @Override 213 public StringBuilder append(long lng) { 214 super.append(lng); 215 return this; 216 } 217 218 @Override 219 public StringBuilder append(float f) { 220 super.append(f); 221 return this; 222 } 223 224 @Override 225 public StringBuilder append(double d) { 226 super.append(d); 227 return this; 228 } 229 230 /** 231 * @since 1.5 232 */ 233 @Override 234 public StringBuilder appendCodePoint(int codePoint) { 235 super.appendCodePoint(codePoint); 236 return this; 237 } 238 239 /** 240 * @throws StringIndexOutOfBoundsException {@inheritDoc} 241 */ 242 @Override 243 public StringBuilder delete(int start, int end) { 244 super.delete(start, end); 245 return this; 246 } 247 248 /** 249 * @throws StringIndexOutOfBoundsException {@inheritDoc} 250 */ 251 @Override 252 public StringBuilder deleteCharAt(int index) { 253 super.deleteCharAt(index); 254 return this; 255 } 256 257 /** 258 * @throws StringIndexOutOfBoundsException {@inheritDoc} 259 */ 260 @Override 261 public StringBuilder replace(int start, int end, String str) { 262 super.replace(start, end, str); 263 return this; 264 } 265 266 /** 267 * @throws StringIndexOutOfBoundsException {@inheritDoc} 268 */ 269 @Override 270 public StringBuilder insert(int index, char[] str, int offset, 271 int len) 272 { 273 super.insert(index, str, offset, len); 274 return this; 275 } 276 277 /** 278 * @throws StringIndexOutOfBoundsException {@inheritDoc} 279 */ 280 @Override 281 public StringBuilder insert(int offset, Object obj) { 282 super.insert(offset, obj); 283 return this; 284 } 285 286 /** 287 * @throws StringIndexOutOfBoundsException {@inheritDoc} 288 */ 289 @Override 290 public StringBuilder insert(int offset, String str) { 291 super.insert(offset, str); 292 return this; 293 } 294 295 /** 296 * @throws StringIndexOutOfBoundsException {@inheritDoc} 297 */ 298 @Override 299 public StringBuilder insert(int offset, char[] str) { 300 super.insert(offset, str); 301 return this; 302 } 303 304 /** 305 * @throws IndexOutOfBoundsException {@inheritDoc} 306 */ 307 @Override 308 public StringBuilder insert(int dstOffset, CharSequence s) { 309 super.insert(dstOffset, s); 310 return this; 311 } 312 313 /** 314 * @throws IndexOutOfBoundsException {@inheritDoc} 315 */ 316 @Override 317 public StringBuilder insert(int dstOffset, CharSequence s, 318 int start, int end) 319 { 320 super.insert(dstOffset, s, start, end); 321 return this; 322 } 323 324 /** 325 * @throws StringIndexOutOfBoundsException {@inheritDoc} 326 */ 327 @Override 328 public StringBuilder insert(int offset, boolean b) { 329 super.insert(offset, b); 330 return this; 331 } 332 333 /** 334 * @throws IndexOutOfBoundsException {@inheritDoc} 335 */ 336 @Override 337 public StringBuilder insert(int offset, char c) { 338 super.insert(offset, c); 339 return this; 340 } 341 342 /** 343 * @throws StringIndexOutOfBoundsException {@inheritDoc} 344 */ 345 @Override 346 public StringBuilder insert(int offset, int i) { 347 super.insert(offset, i); 348 return this; 349 } 350 351 /** 352 * @throws StringIndexOutOfBoundsException {@inheritDoc} 353 */ 354 @Override 355 public StringBuilder insert(int offset, long l) { 356 super.insert(offset, l); 357 return this; 358 } 359 360 /** 361 * @throws StringIndexOutOfBoundsException {@inheritDoc} 362 */ 363 @Override 364 public StringBuilder insert(int offset, float f) { 365 super.insert(offset, f); 366 return this; 367 } 368 369 /** 370 * @throws StringIndexOutOfBoundsException {@inheritDoc} 371 */ 372 @Override 373 public StringBuilder insert(int offset, double d) { 374 super.insert(offset, d); 375 return this; 376 } 377 378 @Override 379 public int indexOf(String str) { 380 return super.indexOf(str); 381 } 382 383 @Override 384 public int indexOf(String str, int fromIndex) { 385 return super.indexOf(str, fromIndex); 386 } 387 388 @Override 389 public int lastIndexOf(String str) { 390 return super.lastIndexOf(str); 391 } 392 393 @Override 394 public int lastIndexOf(String str, int fromIndex) { 395 return super.lastIndexOf(str, fromIndex); 396 } 397 398 @Override 399 public StringBuilder reverse() { 400 super.reverse(); 401 return this; 402 } 403 404 @Override 405 public String toString() { 406 // Create a copy, don't share the array 407 return new String(value, 0, count); 408 } 409 410 /** 411 * Save the state of the {@code StringBuilder} instance to a stream 412 * (that is, serialize it). 413 * 414 * @serialData the number of characters currently stored in the string 415 * builder ({@code int}), followed by the characters in the 416 * string builder ({@code char[]}). The length of the 417 * {@code char} array may be greater than the number of 418 * characters currently stored in the string builder, in which 419 * case extra characters are ignored. 420 */ 421 private void writeObject(java.io.ObjectOutputStream s) 422 throws java.io.IOException { 423 s.defaultWriteObject(); 424 s.writeInt(count); 425 s.writeObject(value); 426 } 427 428 /** 429 * readObject is called to restore the state of the StringBuffer from 430 * a stream. 431 */ 432 private void readObject(java.io.ObjectInputStream s) 433 throws java.io.IOException, ClassNotFoundException { 434 s.defaultReadObject(); 435 count = s.readInt(); 436 value = (char[]) s.readObject(); 437 } 438 439 } | 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 mutable sequence of characters. This class provides an API compatible 31 * with {@code StringBuilder}, but with some additional constraints: 32 * <ul> 33 * <li>mutating methods can only be invoked in the same thread that constructed 34 * the instance. Attempts to invoke them in other threads throw 35 * {@code IllegalStateException} 36 * </li> 37 * <li>once {@link #toString()} has been called (in constructing thread), 38 * no mutating methods can be invoked any more, not even in constructing thread. 39 * Attempts to invoke them throw {@code IllegalStateException} 40 * </li> 41 * </ul> 42 * <p>This enables optimization where the {@code String} constructed 43 * as the final act can reference the character array that was used for building 44 * and no additional copying is needed. This optimization is only effective if 45 * the {@link #length()} == {@link #capacity()} when {@code toString()} is called. 46 * 47 * @see StringBuilder 48 * @since 1.9 49 */ 50 public final class ThreadLocalStringBuilder 51 extends AbstractStringBuilder 52 implements java.io.Serializable, CharSequence 53 { 54 /** use serialVersionUID for interoperability */ 55 static final long serialVersionUID = 1L; 56 57 /** the construction thread until toString() is called, then the String */ 58 private transient Object constructionThreadOrString; 59 60 /** 61 * Constructs a string builder with no characters in it and an 62 * initial capacity of 16 characters. 63 */ 64 public ThreadLocalStringBuilder() { 65 super(16); 66 constructionThreadOrString = Thread.currentThread(); 67 } 68 69 /** 70 * Constructs a string builder with no characters in it and an 71 * initial capacity specified by the {@code capacity} argument. 72 * 73 * @param capacity the initial capacity. 74 * @throws NegativeArraySizeException if the {@code capacity} 75 * argument is less than {@code 0}. 76 */ 77 public ThreadLocalStringBuilder(int capacity) { 78 super(capacity); 79 constructionThreadOrString = Thread.currentThread(); 80 } 81 82 /** 83 * Constructs a string builder initialized to the contents of the 84 * specified string. The initial capacity of the string builder is 85 * {@code 16} plus the length of the string argument. 86 * 87 * @param str the initial contents of the buffer. 88 */ 89 public ThreadLocalStringBuilder(String str) { 90 super(str.length() + 16); 91 constructionThreadOrString = Thread.currentThread(); 92 append(str); 93 } 94 95 /** 96 * Constructs a string builder that contains the same characters 97 * as the specified {@code CharSequence}. The initial capacity of 98 * the string builder is {@code 16} plus the length of the 99 * {@code CharSequence} argument. 100 * 101 * @param seq the sequence to copy. 102 */ 103 public ThreadLocalStringBuilder(CharSequence seq) { 104 this(seq.length() + 16); 105 append(seq); 106 } 107 108 /** 109 * @throws IllegalStateException if not invoked in thread that constructed 110 * this instance or if toString() has already been called. 111 */ 112 private void checkThread() { 113 Object o = constructionThreadOrString; 114 if (o != Thread.currentThread()) { 115 throw new IllegalStateException((o instanceof String) 116 ? "toString() has already been called" 117 : "Illegal mutating thread" 118 ); 119 } 120 } 121 122 /** 123 * @throws IllegalStateException if called from non-constructing thread or 124 * {@code toString()} has already been called 125 */ 126 @Override 127 public ThreadLocalStringBuilder append(Object obj) { 128 checkThread(); 129 return append(String.valueOf(obj)); 130 } 131 132 /** 133 * @throws IllegalStateException if called from non-constructing thread or 134 * {@code toString()} has already been called 135 */ 136 @Override 137 public ThreadLocalStringBuilder append(String str) { 138 checkThread(); 139 super.append(str); 140 return this; 141 } 142 143 /** 144 * Appends the specified {@code StringBuffer} to this sequence. 145 * <p> 146 * The characters of the {@code StringBuffer} argument are appended, 147 * in order, to this sequence, increasing the 148 * length of this sequence by the length of the argument. 149 * If {@code sb} is {@code null}, then the four characters 150 * {@code "null"} are appended to this sequence. 151 * <p> 152 * Let <i>n</i> be the length of this character sequence just prior to 153 * execution of the {@code append} method. Then the character at index 154 * <i>k</i> in the new character sequence is equal to the character at 155 * index <i>k</i> in the old character sequence, if <i>k</i> is less than 156 * <i>n</i>; otherwise, it is equal to the character at index <i>k-n</i> 157 * in the argument {@code sb}. 158 * 159 * @param sb the {@code StringBuffer} to append. 160 * @return a reference to this object. 161 * @throws IllegalStateException if called from non-constructing thread or 162 * {@code toString()} has already been called 163 */ 164 @Override 165 public ThreadLocalStringBuilder append(StringBuffer sb) { 166 checkThread(); 167 super.append(sb); 168 return this; 169 } 170 171 /** 172 * @throws IllegalStateException if called from non-constructing thread or 173 * {@code toString()} has already been called 174 */ 175 @Override 176 public ThreadLocalStringBuilder append(CharSequence s) { 177 checkThread(); 178 super.append(s); 179 return this; 180 } 181 182 /** 183 * @throws IndexOutOfBoundsException {@inheritDoc} 184 * @throws IllegalStateException if called from non-constructing thread or 185 * {@code toString()} has already been called 186 */ 187 @Override 188 public ThreadLocalStringBuilder append(CharSequence s, int start, int end) { 189 checkThread(); 190 super.append(s, start, end); 191 return this; 192 } 193 194 /** 195 * @throws IllegalStateException if called from non-constructing thread or 196 * {@code toString()} has already been called 197 */ 198 @Override 199 public ThreadLocalStringBuilder append(char[] str) { 200 checkThread(); 201 super.append(str); 202 return this; 203 } 204 205 /** 206 * @throws IndexOutOfBoundsException {@inheritDoc} 207 * @throws IllegalStateException if called from non-constructing thread or 208 * {@code toString()} has already been called 209 */ 210 @Override 211 public ThreadLocalStringBuilder append(char[] str, int offset, int len) { 212 checkThread(); 213 super.append(str, offset, len); 214 return this; 215 } 216 217 /** 218 * @throws IllegalStateException if called from non-constructing thread or 219 * {@code toString()} has already been called 220 */ 221 @Override 222 public ThreadLocalStringBuilder append(boolean b) { 223 checkThread(); 224 super.append(b); 225 return this; 226 } 227 228 /** 229 * @throws IllegalStateException if called from non-constructing thread or 230 * {@code toString()} has already been called 231 */ 232 @Override 233 public ThreadLocalStringBuilder append(char c) { 234 checkThread(); 235 super.append(c); 236 return this; 237 } 238 239 /** 240 * @throws IllegalStateException if called from non-constructing thread or 241 * {@code toString()} has already been called 242 */ 243 @Override 244 public ThreadLocalStringBuilder append(int i) { 245 checkThread(); 246 super.append(i); 247 return this; 248 } 249 250 /** 251 * @throws IllegalStateException if called from non-constructing thread or 252 * {@code toString()} has already been called 253 */ 254 @Override 255 public ThreadLocalStringBuilder append(long lng) { 256 checkThread(); 257 super.append(lng); 258 return this; 259 } 260 261 /** 262 * @throws IllegalStateException if called from non-constructing thread or 263 * {@code toString()} has already been called 264 */ 265 @Override 266 public ThreadLocalStringBuilder append(float f) { 267 checkThread(); 268 super.append(f); 269 return this; 270 } 271 272 /** 273 * @throws IllegalStateException if called from non-constructing thread or 274 * {@code toString()} has already been called 275 */ 276 @Override 277 public ThreadLocalStringBuilder append(double d) { 278 checkThread(); 279 super.append(d); 280 return this; 281 } 282 283 /** 284 * @throws IllegalStateException if called from non-constructing thread or 285 * {@code toString()} has already been called 286 * @since 1.5 287 */ 288 @Override 289 public ThreadLocalStringBuilder appendCodePoint(int codePoint) { 290 checkThread(); 291 super.appendCodePoint(codePoint); 292 return this; 293 } 294 295 /** 296 * @throws StringIndexOutOfBoundsException {@inheritDoc} 297 * @throws IllegalStateException if called from non-constructing thread or 298 * {@code toString()} has already been called 299 */ 300 @Override 301 public ThreadLocalStringBuilder delete(int start, int end) { 302 checkThread(); 303 super.delete(start, end); 304 return this; 305 } 306 307 /** 308 * @throws StringIndexOutOfBoundsException {@inheritDoc} 309 * @throws IllegalStateException if called from non-constructing thread or 310 * {@code toString()} has already been called 311 */ 312 @Override 313 public ThreadLocalStringBuilder deleteCharAt(int index) { 314 checkThread(); 315 super.deleteCharAt(index); 316 return this; 317 } 318 319 /** 320 * @throws StringIndexOutOfBoundsException {@inheritDoc} 321 * @throws IllegalStateException if called from non-constructing thread or 322 * {@code toString()} has already been called 323 */ 324 @Override 325 public ThreadLocalStringBuilder replace(int start, int end, String str) { 326 checkThread(); 327 super.replace(start, end, str); 328 return this; 329 } 330 331 /** 332 * @throws StringIndexOutOfBoundsException {@inheritDoc} 333 * @throws IllegalStateException if called from non-constructing thread or 334 * {@code toString()} has already been called 335 */ 336 @Override 337 public ThreadLocalStringBuilder insert(int index, char[] str, int offset, 338 int len) 339 { 340 checkThread(); 341 super.insert(index, str, offset, len); 342 return this; 343 } 344 345 /** 346 * @throws StringIndexOutOfBoundsException {@inheritDoc} 347 * @throws IllegalStateException if called from non-constructing thread or 348 * {@code toString()} has already been called 349 */ 350 @Override 351 public ThreadLocalStringBuilder insert(int offset, Object obj) { 352 checkThread(); 353 super.insert(offset, obj); 354 return this; 355 } 356 357 /** 358 * @throws StringIndexOutOfBoundsException {@inheritDoc} 359 * @throws IllegalStateException if called from non-constructing thread or 360 * {@code toString()} has already been called 361 */ 362 @Override 363 public ThreadLocalStringBuilder insert(int offset, String str) { 364 checkThread(); 365 super.insert(offset, str); 366 return this; 367 } 368 369 /** 370 * @throws StringIndexOutOfBoundsException {@inheritDoc} 371 * @throws IllegalStateException if called from non-constructing thread or 372 * {@code toString()} has already been called 373 */ 374 @Override 375 public ThreadLocalStringBuilder insert(int offset, char[] str) { 376 checkThread(); 377 super.insert(offset, str); 378 return this; 379 } 380 381 /** 382 * @throws IndexOutOfBoundsException {@inheritDoc} 383 * @throws IllegalStateException if called from non-constructing thread or 384 * {@code toString()} has already been called 385 */ 386 @Override 387 public ThreadLocalStringBuilder insert(int dstOffset, CharSequence s) { 388 checkThread(); 389 super.insert(dstOffset, s); 390 return this; 391 } 392 393 /** 394 * @throws IndexOutOfBoundsException {@inheritDoc} 395 * @throws IllegalStateException if called from non-constructing thread or 396 * {@code toString()} has already been called 397 */ 398 @Override 399 public ThreadLocalStringBuilder insert(int dstOffset, CharSequence s, 400 int start, int end) 401 { 402 checkThread(); 403 super.insert(dstOffset, s, start, end); 404 return this; 405 } 406 407 /** 408 * @throws StringIndexOutOfBoundsException {@inheritDoc} 409 * @throws IllegalStateException if called from non-constructing thread or 410 * {@code toString()} has already been called 411 */ 412 @Override 413 public ThreadLocalStringBuilder insert(int offset, boolean b) { 414 checkThread(); 415 super.insert(offset, b); 416 return this; 417 } 418 419 /** 420 * @throws IndexOutOfBoundsException {@inheritDoc} 421 * @throws IllegalStateException if called from non-constructing thread or 422 * {@code toString()} has already been called 423 */ 424 @Override 425 public ThreadLocalStringBuilder insert(int offset, char c) { 426 checkThread(); 427 super.insert(offset, c); 428 return this; 429 } 430 431 /** 432 * @throws StringIndexOutOfBoundsException {@inheritDoc} 433 * @throws IllegalStateException if called from non-constructing thread or 434 * {@code toString()} has already been called 435 */ 436 @Override 437 public ThreadLocalStringBuilder insert(int offset, int i) { 438 checkThread(); 439 super.insert(offset, i); 440 return this; 441 } 442 443 /** 444 * @throws StringIndexOutOfBoundsException {@inheritDoc} 445 * @throws IllegalStateException if called from non-constructing thread or 446 * {@code toString()} has already been called 447 */ 448 @Override 449 public ThreadLocalStringBuilder insert(int offset, long l) { 450 checkThread(); 451 super.insert(offset, l); 452 return this; 453 } 454 455 /** 456 * @throws StringIndexOutOfBoundsException {@inheritDoc} 457 * @throws IllegalStateException if called from non-constructing thread or 458 * {@code toString()} has already been called 459 */ 460 @Override 461 public ThreadLocalStringBuilder insert(int offset, float f) { 462 checkThread(); 463 super.insert(offset, f); 464 return this; 465 } 466 467 /** 468 * @throws StringIndexOutOfBoundsException {@inheritDoc} 469 * @throws IllegalStateException if called from non-constructing thread or 470 * {@code toString()} has already been called 471 */ 472 @Override 473 public ThreadLocalStringBuilder insert(int offset, double d) { 474 checkThread(); 475 super.insert(offset, d); 476 return this; 477 } 478 479 /** 480 * @throws IllegalStateException if called from non-constructing thread or 481 * {@code toString()} has already been called 482 */ 483 @Override 484 public ThreadLocalStringBuilder reverse() { 485 checkThread(); 486 super.reverse(); 487 return this; 488 } 489 490 /** 491 * @throws IllegalStateException if called from non-constructing thread or 492 * {@code toString()} has already been called 493 */ 494 @Override 495 public void ensureCapacity(int minimumCapacity) { 496 checkThread(); 497 super.ensureCapacity(minimumCapacity); 498 } 499 500 /** 501 * @throws IllegalStateException if called from non-constructing thread or 502 * {@code toString()} has already been called 503 */ 504 @Override 505 public void trimToSize() { 506 checkThread(); 507 super.trimToSize(); 508 } 509 510 /** 511 * @throws IllegalStateException if called from non-constructing thread or 512 * {@code toString()} has already been called 513 */ 514 @Override 515 public void setLength(int newLength) { 516 checkThread(); 517 super.setLength(newLength); 518 } 519 520 /** 521 * @throws IllegalStateException if called from non-constructing thread or 522 * {@code toString()} has already been called 523 */ 524 @Override 525 public void setCharAt(int index, char ch) { 526 checkThread(); 527 super.setCharAt(index, ch); 528 } 529 530 /** 531 * @throws IllegalStateException if called from non-constructing thread 532 * and {@code toString()} has not been called yet 533 */ 534 @Override 535 public String toString() { 536 Object o = constructionThreadOrString; 537 if (o == Thread.currentThread()) { 538 String s = (value.length == count) 539 ? new String(value, true) // share the array if of correct length 540 : new String(value, 0, count); // don't share the array otherwise 541 constructionThreadOrString = s; 542 return s; 543 } 544 if (o instanceof String) { // allow multiple calls to toString() 545 return (String) o; 546 } 547 throw new IllegalStateException("Illegal invoking thread"); 548 } 549 550 /** 551 * Save the state of the {@code StringBuilder} instance to a stream 552 * (that is, serialize it). 553 * 554 * @serialData the number of characters currently stored in the string 555 * builder ({@code int}), followed by the characters in the 556 * string builder ({@code char[]}). The length of the 557 * {@code char} array may be greater than the number of 558 * characters currently stored in the string builder, in which 559 * case extra characters are ignored. 560 */ 561 private void writeObject(java.io.ObjectOutputStream s) 562 throws java.io.IOException { 563 s.defaultWriteObject(); 564 s.writeInt(count); 565 s.writeObject(value); 566 } 567 568 /** 569 * readObject is called to restore the state of the ThreadLocalStringBuilder 570 * from a stream. 571 */ 572 private void readObject(java.io.ObjectInputStream s) 573 throws java.io.IOException, ClassNotFoundException { 574 s.defaultReadObject(); 575 count = s.readInt(); 576 value = (char[]) s.readObject(); 577 constructionThreadOrString = Thread.currentThread(); 578 } 579 } |