< prev index next >

src/java.base/share/classes/java/lang/ThreadLocalStringBuilder.java

Print this page




  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 }
< prev index next >