OSDN Git Service

Jumbo patch:
[pf3gnuchains/gcc-fork.git] / libjava / java / lang / StringBuffer.java
1 // StringBuffer.java - Growable strings.
2
3 /* Copyright (C) 1998, 1999, 2000  Free Software Foundation
4
5    This file is part of libgcj.
6
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9 details.  */
10
11 package java.lang;
12 import java.io.Serializable;
13
14 /**
15  * @author Tom Tromey <tromey@cygnus.com>
16  * @date October 23, 1998.  
17  */
18
19 /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
20  * Updated using online JDK 1.2 docs.
21  * Believed complete and correct to JDK 1.2.
22  * Merged with Classpath.
23  */
24
25 /**
26  * <code>StringBuffer</code> represents a changeable <code>String</code>.
27  * It provides the operations required to modify the
28  * <code>StringBuffer</code> including insert, replace, delete, append,
29  * and reverse.
30  * <P>
31  *
32  * <code>StringBuffer</code>s are variable-length in nature, so even if
33  * you initialize them to a certain size, they can still grow larger than
34  * that.  <EM>Capacity</EM> indicates the number of characters the
35  * <code>StringBuffer</code> can have in it before it has to grow (growing
36  * the char array is an expensive operation involving <code>new</code>).
37  * <P>
38  *
39  * Incidentally, the String operator "+" actually is turned into a
40  * <code>StringBuffer</code> operation:
41  * <BR>
42  * <code>a + b</code>
43  * <BR>
44  * is the same as
45  * <BR>
46  * <code>new StringBuffer(a).append(b).toString()</code>.
47  *
48  * @implnote Classpath's StringBuffer is capable of sharing memory with
49  *           Strings for efficiency.  This will help in two instances:
50  *           first, when a StringBuffer is created from a String but is
51  *           never changed, and second, when a StringBuffer is converted
52  *           to a String and the StringBuffer is not changed after that.
53  *
54  * @since JDK1.0
55  * @author Paul Fisher
56  * @author John Keiser
57  * @author Tom Tromey
58  * @see java.lang.String
59  */
60 public final class StringBuffer implements Serializable
61 {
62   /** Append the <code>String</code> value of the argument to this <code>StringBuffer</code>.
63    *  Uses <code>String.valueOf()</code> to convert to
64    *  <code>String</code>.
65    *  @param bool the <code>boolean</code> to convert and append.
66    *  @return this <code>StringBuffer</code>.
67    *  @see java.lang.String#valueOf(boolean)
68    */
69   public StringBuffer append (boolean bool)
70   {
71     return append (String.valueOf(bool));
72   }
73
74   /** Append the <code>char</code> to this <code>StringBuffer</code>.
75    *  @param c the <code>char</code> to append.
76    *  @return this <code>StringBuffer</code>.
77    */
78   public synchronized StringBuffer append (char ch)
79   {
80     ensureCapacity_unsynchronized (count + 1);
81     value[count++] = ch;
82     return this;
83   }
84
85   /** Append the <code>String</code> value of the argument to this <code>StringBuffer</code>.
86    *  Uses <code>String.valueOf()</code> to convert to
87    *  <code>String</code>.
88    *  @param inum the <code>int</code> to convert and append.
89    *  @return this <code>StringBuffer</code>.
90    *  @see java.lang.String#valueOf(int)
91    */
92   public StringBuffer append (int inum)
93   {
94     return append (String.valueOf(inum));
95   }
96
97   /** Append the <code>String</code> value of the argument to this <code>StringBuffer</code>.
98    *  Uses <code>String.valueOf()</code> to convert to
99    *  <code>String</code>.
100    *  @param lnum the <code>long</code> to convert and append.
101    *  @return this <code>StringBuffer</code>.
102    *  @see java.lang.String#valueOf(long)
103    */
104   public StringBuffer append (long lnum)
105   {
106     return append (String.valueOf(lnum));
107   }
108
109   /** Append the <code>String</code> value of the argument to this <code>StringBuffer</code>.
110    *  Uses <code>String.valueOf()</code> to convert to
111    *  <code>String</code>.
112    *  @param fnum the <code>float</code> to convert and append.
113    *  @return this <code>StringBuffer</code>.
114    *  @see java.lang.String#valueOf(float)
115    */
116   public StringBuffer append (float fnum)
117   {
118     return append (String.valueOf(fnum));
119   }
120
121   /** Append the <code>String</code> value of the argument to this <code>StringBuffer</code>.
122    *  Uses <code>String.valueOf()</code> to convert to
123    *  <code>String</code>.
124    *  @param dnum the <code>double</code> to convert and append.
125    *  @return this <code>StringBuffer</code>.
126    *  @see java.lang.String#valueOf(double)
127    */
128   public StringBuffer append (double dnum)
129   {
130     return append (String.valueOf(dnum));
131   }
132
133   /** Append the <code>String</code> value of the argument to this <code>StringBuffer</code>.
134    *  Uses <code>String.valueOf()</code> to convert to
135    *  <code>String</code>.
136    *  @param obj the <code>Object</code> to convert and append.
137    *  @return this <code>StringBuffer</code>.
138    *  @see java.lang.String#valueOf(java.lang.Object)
139    */
140   public StringBuffer append (Object obj)
141   {
142     return append (String.valueOf(obj));
143   }
144
145   /** Append the <code>String</code> to this <code>StringBuffer</code>.
146    *  @param str the <code>String</code> to append.
147    *  @return this <code>StringBuffer</code>.
148    */
149   public synchronized StringBuffer append (String str)
150   {
151     if (str == null)
152       str = "null";
153     int len = str.length();
154     ensureCapacity_unsynchronized (count + len);
155     str.getChars(0, len, value, count);
156     count += len;
157     return this;
158   }
159
160   /** Append the <code>char</code> array to this <code>StringBuffer</code>.
161    *  @param data the <code>char[]</code> to append.
162    *  @return this <code>StringBuffer</code>.
163    *  @exception NullPointerException if <code>str</code> is <code>null</code>.
164    */
165   public StringBuffer append (char[] data)
166   {
167     return append (data, 0, data.length);
168   }
169
170   /** Append the <code>char</code> array to this <code>StringBuffer</code>.
171    *  @param data the <code>char[]</code> to append.
172    *  @param offset the place to start grabbing characters from
173    *         <code>str</code>.
174    *  @param count the number of characters to get from <code>str</code>.
175    *  @return this <code>StringBuffer</code>.
176    *  @exception NullPointerException if <code>str</code> is <code>null</code>.
177    *  @exception IndexOutOfBoundsException if <code>offset</code> or
178    *             <code>offset+len</code> is out of range.
179    */
180   public synchronized StringBuffer append (char[] data, int offset, int count)
181   {
182     ensureCapacity_unsynchronized (this.count + count);
183     System.arraycopy(data, offset, value, this.count, count);
184     this.count += count;
185     return this;
186   } 
187
188   /** Get the total number of characters this <code>StringBuffer</code>
189    *  can support before it must be grown.  Not to be confused with
190    *  <em>length</em>.
191    *  @return the capacity of this <code>StringBuffer</code>
192    *  @see #length()
193    *  @see #ensureCapacity(int)
194    */
195   public int capacity ()
196   {
197     return value.length;
198   }
199
200   /** Get the character at the specified index.
201    *  @param index the index of the character to get, starting at 0.
202    *  @return the character at the specified index.
203    *  @exception IndexOutOfBoundsException if the desired character index
204    *             is not between 0 and length() - 1 (inclusive).
205    */
206   public synchronized char charAt (int index)
207   {
208     if (index >= count)
209       throw new StringIndexOutOfBoundsException (index);
210     return value[index];
211   }
212
213   /** Delete characters from this <code>StringBuffer</code>.
214    *  <code>delete(10, 12)</code> will delete 10 and 11, but not 12.
215    *  @param start the first character to delete.
216    *  @param end the index after the last character to delete.
217    *  @return this <code>StringBuffer</code>.
218    *  @exception StringIndexOutOfBoundsException if <code>start</code>
219    *             or <code>end-1</code> are out of bounds, or if
220    *             <code>start > end</code>.
221    */
222   public synchronized StringBuffer delete (int start, int end)
223   {
224     if (start < 0 || start > count || start > end)
225       throw new StringIndexOutOfBoundsException (start);
226     if (end > count)
227       end = count;
228     // This will unshare if required.
229     ensureCapacity_unsynchronized (count);
230     if (count - end != 0)
231       System.arraycopy (value, end, value, start, count - end);
232     count -= (end - start);
233     return this;
234   }
235
236   /** Delete a character from this <code>StringBuffer</code>.
237    *  @param index the index of the character to delete.
238    *  @return this <code>StringBuffer</code>.
239    *  @exception StringIndexOutOfBoundsException if <code>index</code>
240    *             is out of bounds.
241    */
242   public StringBuffer deleteCharAt(int index)
243   {
244     return delete (index, index + 1);
245   }
246
247   /** Increase the capacity of this <code>StringBuffer</code>.
248    *  This will ensure that an expensive growing operation will not occur
249    *  until <code>minimumCapacity</code> is reached.
250    *  If the capacity is actually already greater than <code>minimumCapacity</code>
251    *  @param minimumCapacity the new capacity.
252    *  @see #capacity()
253    */
254   public synchronized void ensureCapacity (int minimumCapacity)
255   {
256     if (shared || minimumCapacity > value.length)
257       {
258         // We don't want to make a larger vector when `shared' is
259         // set.  If we do, then setLength becomes very inefficient
260         // when repeatedly reusing a StringBuffer in a loop.
261         int max = (minimumCapacity > value.length
262                    ? value.length*2+2
263                    : value.length);
264         minimumCapacity = (minimumCapacity < max ? max : minimumCapacity);
265         char[] nb = new char[minimumCapacity];
266         System.arraycopy(value, 0, nb, 0, count);
267         value = nb;
268         shared = false;
269       }
270   }
271
272   // ensureCapacity is used by several synchronized methods in StringBuffer.
273   // There's no need to synchronize again.
274   private void ensureCapacity_unsynchronized (int minimumCapacity)
275   {
276     if (shared || minimumCapacity > value.length)
277       {
278         // We don't want to make a larger vector when `shared' is
279         // set.  If we do, then setLength becomes very inefficient
280         // when repeatedly reusing a StringBuffer in a loop.
281         int max = (minimumCapacity > value.length
282                    ? value.length*2+2
283                    : value.length);
284         minimumCapacity = (minimumCapacity < max ? max : minimumCapacity);
285         char[] nb = new char[minimumCapacity];
286         System.arraycopy(value, 0, nb, 0, count);
287         value = nb;
288         shared = false;
289       }
290   }
291
292   /** Get the specified array of characters.
293    *  The characters will be copied into the array you pass in.
294    *  @param srcOffset the index to start copying from in the
295    *         <code>StringBuffer</code>.
296    *  @param srcEnd the number of characters to copy.
297    *  @param dst the array to copy into.
298    *  @param dstOffset the index to start copying into <code>dst</code>.
299    *  @exception NullPointerException if dst is null.
300    *  @exception IndexOutOfBoundsException if any source or target
301    *             indices are out of range.
302    *  @see java.lang.System#arrayCopy(java.lang.Object,int,java.lang.Object,int,int)
303    */
304   public synchronized void getChars (int srcOffset, int srcEnd,
305                                      char[] dst, int dstOffset)
306   {
307     if (srcOffset < 0 || srcOffset > srcEnd)
308       throw new StringIndexOutOfBoundsException (srcOffset);
309     int todo = srcEnd - srcOffset;
310     if (srcEnd > count || dstOffset + todo > count)
311       throw new StringIndexOutOfBoundsException (srcEnd);
312     System.arraycopy(value, srcOffset, dst, dstOffset, todo);
313   }
314
315   /** Insert the <code>String</code> value of the argument into this <code>StringBuffer</code>.
316    *  Uses <code>String.valueOf()</code> to convert to
317    *  <code>String</code>.
318    *  @param offset the place to insert.
319    *  @param bool the <code>boolean</code> to convert and insert.
320    *  @return this <code>StringBuffer</code>.
321    *  @exception IndexOutOfBoundsException if <code>offset</code> is out
322    *             of range for this <code>StringBuffer</code>.
323    *  @see java.lang.String#valueOf(boolean)
324    */
325   public StringBuffer insert (int offset, boolean bool)
326   {
327     return insert (offset, bool ? "true" : "false");
328   }
329
330   /** Insert the <code>char</code> argument into this <code>StringBuffer</code>.
331    *  @param offset the place to insert.
332    *  @param ch the <code>char</code> to insert.
333    *  @return this <code>StringBuffer</code>.
334    *  @exception IndexOutOfBoundsException if <code>offset</code> is out
335    *             of range for this <code>StringBuffer</code>.
336    */
337   public synchronized StringBuffer insert (int offset, char ch)
338   {
339     if (offset < 0 || offset > count)
340       throw new StringIndexOutOfBoundsException (offset);
341     ensureCapacity_unsynchronized (count+1);
342     System.arraycopy(value, offset, value, offset+1, count-offset);
343     value[offset] = ch;
344     count++;
345     return this;
346   }
347
348   /** Insert the <code>String</code> value of the argument into this <code>StringBuffer</code>.
349    *  Uses <code>String.valueOf()</code> to convert to
350    *  <code>String</code>.
351    *  @param offset the place to insert.
352    *  @param inum the <code>int</code> to convert and insert.
353    *  @return this <code>StringBuffer</code>.
354    *  @exception IndexOutOfBoundsException if <code>offset</code> is out
355    *             of range for this <code>StringBuffer</code>.
356    *  @see java.lang.String#valueOf(int)
357    */
358   public StringBuffer insert (int offset, int inum)
359   {
360     return insert (offset, String.valueOf(inum));
361   }
362
363   /** Insert the <code>String</code> value of the argument into this <code>StringBuffer</code>.
364    *  Uses <code>String.valueOf()</code> to convert to
365    *  <code>String</code>.
366    *  @param offset the place to insert.
367    *  @param lnum the <code>long</code> to convert and insert.
368    *  @return this <code>StringBuffer</code>.
369    *  @exception IndexOutOfBoundsException if <code>offset</code> is out
370    *             of range for this <code>StringBuffer</code>.
371    *  @see java.lang.String#valueOf(long)
372    */
373   public StringBuffer insert (int offset, long lnum)
374   {
375     return insert (offset, String.valueOf(lnum));
376   }
377
378   /** Insert the <code>String</code> value of the argument into this <code>StringBuffer</code>.
379    *  Uses <code>String.valueOf()</code> to convert to
380    *  <code>String</code>.
381    *  @param offset the place to insert.
382    *  @param fnum the <code>float</code> to convert and insert.
383    *  @return this <code>StringBuffer</code>.
384    *  @exception IndexOutOfBoundsException if <code>offset</code> is out
385    *             of range for this <code>StringBuffer</code>.
386    *  @see java.lang.String#valueOf(float)
387    */
388   public StringBuffer insert (int offset, float fnum)
389   {
390     return insert (offset, String.valueOf(fnum));
391   }
392
393   /** Insert the <code>String</code> value of the argument into this <code>StringBuffer</code>.
394    *  Uses <code>String.valueOf()</code> to convert to
395    *  <code>String</code>.
396    *  @param offset the place to insert.
397    *  @param dnum the <code>double</code> to convert and insert.
398    *  @return this <code>StringBuffer</code>.
399    *  @exception IndexOutOfBoundsException if <code>offset</code> is out
400    *             of range for this <code>StringBuffer</code>.
401    *  @see java.lang.String#valueOf(double)
402    */
403   public StringBuffer insert (int offset, double dnum)
404   {
405     return insert (offset, String.valueOf(dnum));
406   }
407
408   /** Insert the <code>String</code> value of the argument into this <code>StringBuffer</code>.
409    *  Uses <code>String.valueOf()</code> to convert to
410    *  <code>String</code>.
411    *  @param offset the place to insert.
412    *  @param obj the <code>Object</code> to convert and insert.
413    *  @return this <code>StringBuffer</code>.
414    *  @exception IndexOutOfBoundsException if <code>offset</code> is out
415    *             of range for this <code>StringBuffer</code>.
416    *  @see java.lang.String#valueOf(java.lang.Object)
417    */
418   public StringBuffer insert (int offset, Object obj)
419   {
420     return insert (offset, String.valueOf(obj));
421   }
422
423   /** Insert the <code>String</code> argument into this <code>StringBuffer</code>.
424    *  @param offset the place to insert.
425    *  @param str the <code>String</code> to insert.
426    *  @return this <code>StringBuffer</code>.
427    *  @exception IndexOutOfBoundsException if <code>offset</code> is out
428    *             of range for this <code>StringBuffer</code>.
429    */
430   public synchronized StringBuffer insert (int offset, String str)
431   {
432     if (offset < 0 || offset > count)
433       throw new StringIndexOutOfBoundsException (offset);
434     // Note that using `null' is from JDK 1.2.
435     if (str == null)
436       str = "null";
437     int len = str.length();
438     ensureCapacity_unsynchronized (count+len);
439     System.arraycopy(value, offset, value, offset+len, count-offset);
440     str.getChars(0, len, value, offset);
441     count += len;
442     return this;
443   }
444
445   /** Insert the <code>char[]</code> argument into this
446    *  <code>StringBuffer</code>. 
447    *  @param offset the place to insert.
448    *  @param data the <code>char[]</code> to insert.
449    *  @return this <code>StringBuffer</code>.
450    *  @exception NullPointerException if <code>data</code> is
451    *             <code>null</code>.
452    *  @exception IndexOutOfBoundsException if <code>offset</code> is out
453    *             of range for this <code>StringBuffer</code>.
454    */
455   public StringBuffer insert (int offset, char[] data)
456   {
457     return insert (offset, data, 0, data.length);
458   }
459
460   /** Insert the <code>char[]</code> argument into this
461    *  <code>StringBuffer</code>.
462    *  @param offset the place to insert.
463    *  @param str the <code>char[]</code> to insert.
464    *  @param str_offset the index in <code>str</code> to start inserting
465    *         from.
466    *  @param len the number of characters to insert.
467    *  @return this <code>StringBuffer</code>.
468    *  @exception NullPointerException if <code>str</code> is <code>null</code>.
469    *  @exception IndexOutOfBoundsException if <code>offset</code> is out
470    *             of range, for this <code>StringBuffer</code>, or if
471    *             <code>str_offset</code> or <code>str_offset+len</code>
472    *             are out of range for <code>str</code>.
473    */
474   public synchronized StringBuffer insert(int offset, char[] str,
475                                           int str_offset, int len)
476   {
477     if (offset < 0 || offset > count)
478       throw new StringIndexOutOfBoundsException (offset);
479     if (len < 0)
480       throw new StringIndexOutOfBoundsException (len);
481     if (str_offset < 0 || str_offset + len > str.length)
482       throw new StringIndexOutOfBoundsException (str_offset);
483     ensureCapacity_unsynchronized (count + len);
484     System.arraycopy(value, offset, value, offset + len, count - offset);
485     System.arraycopy(str, str_offset, value, offset, len);
486     count += len;
487     return this;
488   }
489
490   /** Get the length of the <code>String</code> this
491    *  <code>StringBuffer</code> would create.  Not to be confused with the
492    *  <em>capacity</em> of the <code>StringBuffer</code>.
493    *  @return the length of this <code>StringBuffer</code>.
494    *  @see #capacity()
495    *  @see #setLength()
496    */
497   public int length ()
498   {
499     return count;
500   }
501
502   /** Replace characters between index <code>start</code> (inclusive) and 
503    *  <code>end</code> (exclusive) with <code>str</code>. If <code>end</code> 
504    *  is larger than the size of this StringBuffer, all characters after
505    *  <code>start</code> are replaced.
506    *  @param start the beginning index of characters to delete (inclusive).
507    *  @param end the ending index of characters to delete (exclusive).
508    *  @param str the new <code>String</code> to insert.
509    *  @return this <code>StringBuffer</code>.
510    */
511   public synchronized StringBuffer replace (int start, int end, String str)
512   {
513     if (start < 0 || start > count || start > end)
514       throw new StringIndexOutOfBoundsException (start);
515   
516     int len = str.length();
517     // Calculate the difference in 'count' after the replace.
518     int delta = len - ((end > count ? count : end) - start);
519     ensureCapacity_unsynchronized (count + delta);
520         
521     if (delta != 0 && end < count)
522       System.arraycopy(value, end, value, end + delta, count - end);
523     
524     str.getChars (0, len, value, start);    
525     count += delta;    
526     return this;    
527   }
528
529   /** Reverse the characters in this StringBuffer.
530    *  @return this <code>StringBuffer</code>.
531    */
532   public synchronized StringBuffer reverse ()
533   {
534     // Call ensureCapacity to enforce copy-on-write.
535     ensureCapacity_unsynchronized (count);
536     for (int i = 0; i < count / 2; ++i)
537       {
538         char c = value[i];
539         value[i] = value[count - i - 1];
540         value[count - i - 1] = c;
541       }
542     return this;
543   }
544
545   /** Set the character at the specified index.
546    *  @param index the index of the character to set starting at 0.
547    *  @param ch the value to set that character to.
548    *  @exception IndexOutOfBoundsException if the specified character
549    *             index is not between 0 and length() - 1 (inclusive).
550    */
551   public synchronized void setCharAt (int index, char ch)
552   {
553     if (index < 0 || index >= count)
554       throw new StringIndexOutOfBoundsException (index);
555     // Call ensureCapacity to enforce copy-on-write.
556     ensureCapacity_unsynchronized (count);
557     value[index] = ch;
558   }
559
560   /** Set the length of this StringBuffer.
561    *  <P>
562    *  If the new length is greater than the current length, all the new
563    *  characters are set to '\0'.
564    *  <P>
565    *  If the new length is less than the current length, the first
566    *  <code>newLength</code> characters of the old array will be
567    * @param newLength the new length
568    * @exception IndexOutOfBoundsException if the new length is
569    *            negative.
570    * @see #length()
571    */
572   public synchronized void setLength (int newLength)
573   {
574     if (newLength < 0)
575       throw new StringIndexOutOfBoundsException (newLength);
576
577     ensureCapacity_unsynchronized (newLength);
578     for (int i = count; i < newLength; ++i)
579       value[i] = '\0';
580     count = newLength;
581   }
582
583   /** Create a new StringBuffer with default capacity 16.
584    *  @see JLS 20.13.1
585    */
586   public StringBuffer ()
587   {
588     this (DEFAULT_CAPACITY);
589   }
590
591   /** Create an empty <code>StringBuffer</code> with the specified initial capacity.
592    *  @param capacity the initial capacity.
593    */
594   public StringBuffer (int capacity)
595   {
596     count = 0;
597     value = new char[capacity];
598     shared = false;
599   }
600
601   /** Create a new <code>StringBuffer</code> with the characters in the specified <code>String</code>.
602    *  Initial capacity will be the size of the String plus 16.
603    *  @param str the <code>String</code> to make a <code>StringBuffer</code> out of.
604    *  @XXX optimize for sharing.
605    */
606   public StringBuffer (String str)
607   {
608     // The documentation is not clear, but experimentation with
609     // other implementations indicates that StringBuffer(null)
610     // should throw a NullPointerException.
611     count = str.length();
612     // JLS: The initial capacity of the string buffer is 16 plus the
613     // length of the argument string.
614     value = new char[count + DEFAULT_CAPACITY];
615     str.getChars(0, count, value, 0);
616     shared = false;
617   }
618
619   /**
620    * Creates a substring of this StringBuffer, starting at a specified index
621    * and ending at the end of this StringBuffer.
622    *
623    * @param beginIndex index to start substring (base 0)
624    * 
625    * @return new String which is a substring of this StringBuffer
626    *
627    * @exception StringIndexOutOfBoundsException 
628    *   if (beginIndex < 0 || beginIndex > this.length())
629    */
630   public String substring (int beginIndex)
631   {
632     return substring (beginIndex, count);
633   }
634
635   /**
636    * Creates a substring of this StringBuffer, starting at a specified index
637    * and ending at one character before a specified index.
638    *
639    * @param beginIndex index to start substring (base 0)
640    * @param endIndex index after the last character to be 
641    *   copied into the substring
642    * 
643    * @return new String which is a substring of this StringBuffer
644    *
645    * @exception StringIndexOutOfBoundsException 
646    *   if (beginIndex < 0 || endIndex > this.length() || beginIndex > endIndex)
647    */
648   public synchronized String substring (int beginIndex, int endIndex) 
649   {
650     if (beginIndex < 0 || endIndex > count || beginIndex > endIndex)
651       throw new StringIndexOutOfBoundsException ();
652     // FIXME: for libgcj it would be possible, and more efficient, to
653     // enable sharing here.
654     return new String (value, beginIndex, endIndex - beginIndex);
655   }
656
657   /** Convert this <code>StringBuffer</code> to a <code>String</code>.
658    *  @return the characters in this StringBuffer
659    */
660   public String toString ()
661   {
662     // Note: in libgcj this causes the StringBuffer to be shared.  In
663     // Classpath it does not.
664     return new String (this);
665   }
666
667   // Index of next available character.  Note that this has
668   // permissions set this way so that String can get the value.
669   int count;
670
671   // The buffer.  Note that this has permissions set this way so that
672   // String can get the value.
673   char[] value;
674
675   // True if we need to copy the buffer before writing to it again.
676   // FIXME: JDK 1.2 doesn't specify this.  The new buffer-growing
677   // semantics make this less useful in that case, too.  Note that
678   // this has permissions set this way so that String can get the
679   // value.
680   boolean shared;
681
682   static final long serialVersionUID = 3388685877147921107L;
683   private final static int DEFAULT_CAPACITY = 16; // JLS 20.13.1
684 }