工大后院

 找回密码
 加入后院

扫一扫,访问微社区

QQ登录

只需一步,快速开始

搜索
查看: 1908|回复: 2

Jdk1.4 和jdk1.5中的StringBuffer的不同

[复制链接]
发表于 2006-12-7 12:08 | 显示全部楼层 |阅读模式
偶尔发现,Jdk1.4 和 jdk1.5 中的 StringBuffer有些不同,做了个简单调查
toString() 方法
jdk1.4 中: StringBuffer 的 toString() 是这样实现的:

public String toString() {
       return new String( this );
}

继续跟踪到 String 的构造函数:
public String (StringBuffer buffer) {
        synchronized (buffer) {
            buffer.setShared();
            this . value = buffer.getValue();
            this . offset = 0;
            this . count = buffer.length();
        }
}
没有重新 new 内存空间,是共享的,这个时候首先想到的问题,如果 StringBuffer 变了, String 怎么办?
继续看 StringBuffer 的操做,例如 deleteCharAt ()
public synchronized StringBuffer deleteCharAt( int index) {
        if ((index < 0) || (index >= count ))
           throw new StringIndexOutOfBound***ception();
       if ( shared )
           copy();
       System.arraycopy( value , index+1, value , index, count -index-1);
       count --;
        return this ;
}
当 StringBuffer 改变的时候 , 判断了是否 shared, 然後决定是否 copy
而且为了避免同步问题,把方法做成同步的
jdk1.5 :
public synchronized String toString() {
       return new String( value , 0, count );
}
跟踪进入 String
public String( char value[], int offset, int count) {
        if (offset < 0) {
            throw new StringIndexOutOfBound***ception(offset);
        }
        if (count < 0) {
            throw new StringIndexOutOfBound***ception(count);
        }
        // Note: offset or count might be near -1>>>1.
        if (offset > value. length - count) {
            throw new StringIndexOutOfBound***ception(offset + count);
        }
        char [] v = new char [count];
        System.arraycopy(value, offset, v, 0, count);
        this . offset = 0;
        this . count = count;
        this . value = v;
}
重新分配了内存空间。  
再来看看 StringBuffer 的 deleteCharAt
public synchronized StringBuffer deleteCharAt( int index) {
        super .deleteCharAt(index);
        return this ;
}
有了继承关系,先不管,继续
public AbstractStringBuilder deleteCharAt( int index) {
        if ((index < 0) || (index >= count ))
           throw new StringIndexOutOfBound***ception(index);
       System.arraycopy( value , index+1, value , index, count -index-1);
       count --;
        return this ;
}
不需要判断,也不需要 copy 了

[ 本帖最后由 hexq 于 2006-12-7 12:14 编辑 ]
 楼主| 发表于 2006-12-7 12:08 | 显示全部楼层
既然看到了继承关系,那我们先看一下这个继承关系,再得出结论
发现
abstract class AbstractStringBuilder implements Appendable, CharSequence
然後
public final class StringBuffer  extends AbstractStringBuilder  implements java.io.Serializable, CharSequence
public final class StringBuilder    extends AbstractStringBuilder   implements java.io.Serializable, CharSequence
看一下 document 的解释
StringBuffer 线 程安全的可 变 字符序列。
StringBuilder 一个可 变 的字符序列。
看一下 document 的解释现在可以大概做一下总结了:
首先 toString() 方法 1.4 是不 new 新空间的,把 new 新空间推后到 StringBuffer 再次被更改,提高了性能。
StirngBuffer 的一些方法是同步的

Jdk1.5 区别对待,加入了继承关系,加入了 StringBuilder
StringBuffer 是线程安全的,同步的方法
StringBuilder 的是线程不安全,非同步的
在同步方面 jdk1.5 提供了更多的选择。

疑问,为什么 jdk1.5 中, StringBuffer 改变了 toString() 的实现呢
暂时还没找到好的原因,大部份原因都比较牵强。

[ 本帖最后由 hexq 于 2006-12-7 12:10 编辑 ]
回复

使用道具 举报

发表于 2006-12-7 12:47 | 显示全部楼层
jdk1.4 中: StringBuffer 的 toString() 是这样实现的:
public String toString() {
       return new String( this );
}


jdk1.5 中: StringBuffer 的 toString() 是这样实现的:
public synchronized String toString() {
            return new String(value, 0, count);
}


1.4的源码我没有去看,按楼主给出的1.4代码,差别只在1.5多了个同步语句 synchronized

String类在1.4和1.5中的实现也不一样了,那么StringBuffer在1.5中的toString方法即使按1.4的方法来实现也变得一样了。
在1.5中,String类的两个构造方法:
    public String(StringBuffer buffer) {
// 一开始就来个 buffer.toString(); ,等于调用了String类的public String(char value[], int offset, int count)构造方法
    String result = buffer.toString();
        this.value = result.value;
        this.count = result.count;
        this.offset = result.offset;
    }

    public String(char value[], int offset, int count) {
        if (offset < 0) {
            throw new StringIndexOutOfBound***ception(offset);
        }
        if (count < 0) {
            throw new StringIndexOutOfBound***ception(count);
        }
        // Note: offset or count might be near -1>>>1.
        if (offset > value.length - count) {
            throw new StringIndexOutOfBound***ception(offset + count);
        }
        char[] v = new char[count];
        System.arraycopy(value, offset, v, 0, count);
        this.offset = 0;
        this.count = count;
        this.value = v;
    }


其中value是字符数组。

在1.5中,StringBuffer类里几乎全部方法都为同步方法,原因是在1.5中有了个StringBuilder类吧?!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入后院

本版积分规则

QQ|Archiver|手机版|小黑屋|广告业务Q|工大后院 ( 粤ICP备10013660号 )

GMT+8, 2025-5-16 10:10

Powered by Discuz! X3.5

Copyright © 2001-2024 Tencent Cloud.

快速回复 返回顶部 返回列表