码迷,mamicode.com
首页 > 编程语言 > 详细

java中String和StringBuffer以及StringBuilder的区别

时间:2015-04-16 20:01:23      阅读:137      评论:0      收藏:0      [点我收藏+]

标签:

我个人觉得理解String和StringBuffer以及StringBuilder的区别比较重要.在讨论他们的区别时,我们首先应该知道java中的String.

首先讨论String.

翻看String.java源码,会知道string的一个重要秘密:

在string中,其实内部是通过一个char数组来维护这个string的,并且还定义了一个记录该string在这个数组的起始位置的索引,以及定义了这个string的长度.  重点是他们都是final类型.

    private final char[] value;

    private final int offset;

    private final int count;
我们知道final修饰的变量是不可更改的.所以很快不得不接受一个现实:java中每一个string其实都是不可以更改的. 所以如果需要对一个string内的字符进行更改/移动等操作很显然是不可的. 这个时候会很快发现string中的方法replace()不是就可以更改一个string吗?为了消除这个问号,我们就来看看replace其中一个源码:

    public String replace(char oldChar, char newChar) {
        char[] buffer = value;
        int _offset = offset;
        int _count = count;

        int idx = _offset;
        int last = _offset + _count;
        boolean copied = false;
        while (idx < last) {
            if (buffer[idx] == oldChar) {
                if (!copied) {
                    char[] newBuffer = new char[_count];
                    System.arraycopy(buffer, _offset, newBuffer, 0, _count);
                    buffer = newBuffer;
                    idx -= _offset;
                    last -= _offset;
                    copied = true;
                }
                buffer[idx] = newChar;
            }
            idx++;
        }

        return copied ? new String(0, count, buffer) : this;
    }
这个方法目的就是用newChar替换string中的所有的oldChar. 从上面的代码可以清楚的知道:当替换成功时候返回的其实是一个新的string,也就是说并不是原来的那个string对象.

还包括substring在内的所以其他方法,貌似是在改这个string,其实都不是,最后都是new了一个新的string.

这样一来问题就来了:往往实际开发中,对一个string反复修改是再正常不过的事情了,而且有时候我们还会高频率的这么做,如果每次操作都是new一个新的string,显然是不可的.在这种情况下StringBuffer和StringBuilder就出现了!目的就是为了解决这一问题.

查看StringBuffer和StringBuilder的源码会很快发现:其实他们几乎都一样,唯一的区别就是StringBuffer的几乎所有方法都采用了synchronized来同步,所以StringBuffer和StringBuilder区别就是线程安全问题.

所以接下来讨论的焦点就是StringBuffer如何实现对字符串的修改的.

StringBuffer和StringBuilder都是实现了虚类:AbstractStringBuilder,其中关键功能的实现都在这个虚类中,在AbstractStringBuilder中用一个char数组来维护这个字符串的,并且也定义了字符串的长度,如下代码所示:

    private char[] value;

    private int count;
这个和string里面定义的final char[] value不一样. 这里看看append()其中一个方法的实现:

    final void append0(String string) {
        if (string == null) {
            appendNull();
            return;
        }
        int length = string.length();
        int newCount = count + length;
        if (newCount > value.length) {
            enlargeBuffer(newCount);
        }
        string._getChars(0, length, value, count);
        count = newCount;
    }
上面的方法就是给StringBuffer或者StringBuilder后面追加一个string: 首先是确定当前的字符串数组长度是否不够,如果不够就扩容,然后将需要追加的string通过方法拷贝到value中.

从中可以发现,由于StringBuffer里面的字符数组value不是final,所以可以对其更改.而不需要像String那样new一个新的String对象.

java中String和StringBuffer以及StringBuilder的区别

标签:

原文地址:http://blog.csdn.net/green_shing/article/details/45071073

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!