首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >java之StringBuilder源码分析知多少?

java之StringBuilder源码分析知多少?

作者头像
码农王同学
发布2019-10-23 16:39:50
发布2019-10-23 16:39:50
3910
举报
文章被收录于专栏:后端Coder后端Coder
其实,每次写文章的时候,脑海中总是浮现程序员这样的关键字,自己对程序员三个字的理解或许与别人理解的不一样。有人问你是程序员,不,我是码农。或许码农也算不上,坏笑。

今天我们想说的是的String,StringBuffer,StringBuilder的区别在哪?每个人都会有不同的理解和心得,自己在这分享一下自己的一些理解了。我还是按照自己的风格,先写上代码然后慢慢分析的过程进行咯,希望可以帮助到你。

Tips:代码左右滑动,可以看到完整代码。

代码语言:javascript
复制
public static void main(String[] args) {
        String outPutStr = "hello,后端Coder";
        System.out.println(outPutStr);
        System.out.println("==============下面介绍StringBuffer用法=====================");
        String outPut = useStringBuffer("hello,");
        System.out.println(outPut);//hello,欢迎关注wechat公众号后端Coder
        System.out.println("==============下面介绍StringBuilder用法=====================");
        String  outPutStringBuilder = useStringBuilder("后端Coder");
        System.out.println(outPutStringBuilder);//hello,后端Coder
    }

    private static String useStringBuffer(String str) {
        StringBuffer stringBuffer = new StringBuffer(16);
        stringBuffer.append(str);
        stringBuffer.append("欢迎关注");
        stringBuffer.append("wechat");
        stringBuffer.append("公众号后端Coder");
        return stringBuffer.toString();
    }

    private static String useStringBuilder(String str) {
        StringBuilder stringBuilder = new StringBuilder(16);
        stringBuilder.append("hello,");
        stringBuilder.append(str);
        return stringBuilder.toString();
    }

好的,将上面的代码在自己的IDE环境里面运行一下,效果一目了然,清晰可见,下面我们说下他们的区别吧,StringBuffer相对于StringBuilder主要是在方法上进行了加锁的限制,多线程下是线程安全的,StringBuilder在方法上没有加上synchroized关键字的修饰,没有进行同步锁的限制,多线程下未必安全。

两者的共同特点大部分都是进行字符串的拼接来使用的,一般我们定义一个字符串,常规写法如下:

代码语言:javascript
复制
String outPutStr = "hello,后端Coder";
System.out.println(outPutStr);

当然了,这是常规的写法,还有特别的,就是多个字符串进行拼接,可能会存在这样的写法:

代码语言:javascript
复制
System.out.println("==============下面介绍useStringAppend用法=====================");
String content = useStringAppend("文章");
System.out.println(content);//hello,很感谢在这里遇到你阅读这篇文章
private static String useStringAppend(String str){
  return "hello,"+"很感谢在这里遇到你"+"阅读这篇"+str;
 }

多个字符串拼接时,建议使用StringBuilder或者StringBuffer的append()方法进行来做,这样在字符串拼接时性能会更好一下,后面会单独写上一篇关于计时消耗统计的文章,在这里就先暂时不讲嘞,自己写文章,还是细分到一个点进行来说吧,避免读者觉得很没意思,自己也要遵守自己当初为什么写文章的初衷,坏笑。

下面我们继续回到正题吧,我们看下两者的构造函数,先看下StringBuffer的构造函数下,源码如下:

代码语言:javascript
复制
第一步,我们通过构造函数进入到下面的这个方法
public StringBuffer(int capacity) {
        super(16);
 }
代码语言:javascript
复制
第二步,我们点击super(capacity)进入下面的方法
AbstractStringBuilder(int capacity) {
        value = new char[capacity];
 }
代码语言:javascript
复制
第三步,我们看下第二步的value就是数组了,定义的一个字符数组的成员变量
/**
 * The value is used for character storage.
 */
 char[] value;

到这里,StringBuffer的构造函数流程就走完了,这里我们看到,如果我们没有给构造添加一个capacity容量,在调用super()方法时,会默认传进一个capaicty=16大小的数值进去,初始化字符数组大小为16,这是因为预分配机制的存在,当我们可以预估数组的大小时,还是给数组进行设置一个大小,避免扩容带来的消耗和内存空间的浪费,同样StringBuilder的构造函数也一样。

ok,我们继续说下为什么StringBuffer是线程安全的,直接看代码咯:

代码语言:javascript
复制
由于文章的篇幅原因,这里我们只看下这三个方法了,三个方法的作用根据方法名,大家
就知道方法的作用了,在这三个方法上面都有synchronized关键字的修饰,这就是使用
同步机制保证的线程安全的。
代码语言:javascript
复制
 public synchronized int length() {
        return count;
 }
    
  public synchronized int capacity() {
        return value.length;
  }
    
  public synchronized void ensureCapacity(int minimumCapacity) {
        if (minimumCapacity > value.length) {
            expandCapacity(minimumCapacity);
        }

同样StringBuilder的流程也是这样的,ok,到这里我们的文章也就是要结束了,希望这篇文章可以帮助到此时此刻正在阅读的你

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农王同学 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档