[jdom-interest] Text class (Modified)

Steve Odendahl steve.odendahl at central.sun.com
Mon May 28 08:07:18 PDT 2001


Reusing the StringBuffer may not be a good idea, at least 
prior to JDK1.3.  Check out bug ID 4295713.

Basically, what can happen is this ...

StringBuffer reuseMe = new StringBuffer ();

// ... append lots of stuff to reuseMe, making reuseMe's 
// internal char[] (for example) 5000 characters long

String longString = reuseMe.toString ();
// longString uses reuseMe's 5000 long char[], and the shared
// flag in reuseMe is set to true.

reuseMe.setLength (0);
// since reuseMe's shared flag is true, reuseMe creates a new
// internal char[] of length 5000 (in JDK1.3 this was patched
// to reset to the default length of 16 when the new length
// is 0), and the shared flag is set to false.

// ... append a little bit of stuff to reuseMe, making its
// length (for example) 3 characters

String shortString = reuseMe.toString ();
// Even though shortString is 3 characters long, it uses
// an underlying char[] of length 5000.  If the reference
// to shortString is held for a long time ... :-( 

I learned this from a talk given at JavaOne 2000 by Craig
Larman of Valtech.

	Steve Odendahl
	(Not speaking for Sun Microsystems, Inc.)

At approximately 06:51:02 PM on Sun, May 27, 2001,
Amy Lewis sent this message:
> Yah, there was just a suggestion to reuse the string buffer, instead of
> making a new one each time the value is set, so:
> 
> On Sun, May 27, 2001 at 04:42:12PM -0500, Brett McLaughlin wrote:
> >OK. So now we're at:
> >
> >public class Text {
> >
> >    private StringBuffer value;
> 
> private StringBuffer value = new StringBuffer();
> 
> >    private Element parent;
> >
> >    protected Text() { }
> >
> >    public Text(String stringValue) {
> >        value = new StringBuffer(stringValue);
> 
> value.setLength(0);
> value.append(stringValue);
> 
> >    }
> >
> >    public String getValue() {
> >        return value.toString();
> >    }
> 
> Since the underlying abstraction is a StringBuffer, is it permissible
> to expose that for those who want to be able to use replace() et alii
> without creating a new SB then calling setValue?  If so:
> 
>     public StringBuffer getBuffer() {
>         return value;
>     }
> 
> The question is: would this cause inflexibility if, in future, some
> other implementation were chosen?  It's easy enough, of course, to
> return new StringBuffer(getValue()), but that won't work ... if the
> semantics are to be that the returned buffer is live (changing it
> changes the owning Text).  So it's presented for discussion.
> 
> >
> >    public void setValue(String stringValue) {
> >        value = new StringBuffer(stringValue);
> 
> value.setLength(0);
> value.append(stringValue);
> 
> >    }
> 
> You might also want (for ease in copying)
> 
> public void setValue(Text other)
> {
>     value.setLength(0);
>     value.append(other.value);
> }
> 
> (ugh, needs a test for null)
> 
> >
> >    public void append(String stringValue) {
> >        value.append(stringValue);
> >    }
> >
> >    public Element getParent() {
> >        return parent;
> >    }
> >
> >    protected void setParent(Element parent) {
> >        this.parent = parent;
> >    }
> >
> >    public String toString() {
> >        return getValue();
> >    }
> >
> >    public int hashCode() {
> >        return value.toString().hashCode();
> >    }
> >
> >    public Object clone() {
> >        Text newText = new Text(value);
> >        newText.setParent(parent);
> >    }
> >
> >    public boolean equals(Object ob) {
> >        if (ob instanceof Text) {
> >            if (((Text)ob).value.equals(value)) {
> >                return true;
> >            }
> >        }
> >        return false;
> >    }
> 
> I'd suggest allowing this to be polymorphic, although I'm not quite
> certain that this is the best thing to do.  If you did so, then you'd
> add: else if (ob instanceof StringBuffer) { ... } else if (ob instanceof
> String) { ... }
> 
> However, I dunno if this is necessarily the semantics that equals ought
> to have.  So consider it for discussion only.
> 
> >}
> 
> Amy!




More information about the jdom-interest mailing list