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