通过源码分析String、StringBuffer和StringBuilder

本文通过对String、StringBuffer和StringBuilder的源码分析及性能测试,揭示它们的区别。String是不可变的,适用于字符串常量;StringBuilder非线程安全,适合单线程频繁修改字符串;StringBuffer线程安全,多线程环境下推荐使用。性能方面,StringBuilder最快,然后是StringBuffer,由于synchronized关键字的存在,StringBuffer稍慢。
摘要由CSDN通过智能技术生成

0x00 简介

又翻出来了在15年整理的笔记了。感觉当初还是挺较真的。

自己对String的理解总是存在着不同程度的误差,经常处于一知半解的状态,而且对其内部的原理也不是特别清楚,碰巧又和同学聊起这个知识点,秉承爱折腾的原则,在论文答辩之际详细整理一下。

0x01 说明

最初听说的String、StringBuffer和StringBuilder三者之间的区别主要是下面这个版本(略作总结):

  • String:字符串常量,字符串长度不可变。Java中String是immutable(不可变)的。用于存放字符的数组被声明为final的,因此只能赋值一次,不可再更改。

  • StringBuffer:字符串变量(Synchronized,即线程安全)。如果要频繁对字符串内容进行修改,出于效率考虑最好使用StringBuffer,如果想转成String类型,可以调用StringBuffer的toString()方法。

  • StringBuilder:字符串变量(非线程安全)。在内部,StringBuilder对象被当作是一个包含字符序列的变长数组。

  • 一般情况下,速度从快到慢:StringBuilder > StringBuffer > String。

0x02 详细分析

下面通过不同的角度来对这三个String相关的类型进行详细的分析和学习,主要通过源码以及反编译的字节码进行学习,另外对于常拿来比较三者之间性能的例子就不再重复了,整理下面内容的主要目标是深入理解这三者的区别。

下面将分别对这三者进行说明,都先从源码中观测一下其创建的过程,以及如何进行添加操作,随后对三个类型做同一种测试,即字符串的拼接,通过虚指令观测其虚拟机层面的执行原理,最后做一个总结。

String

源码

下面是String在jdk中的源码片段,可以看出,String类中实际存放数据是一个以final 类型的char数组,也就是说该数组是不可变的。


public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
   
    private final char value[];

    public String() {
        this.value = new char[0];
    }

    public String(char value[]) {
        this.value = Arrays.copyOf(value, value.length);
    }

    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }
}
例子

简单代码

public class StringTest {
   
    public static void main(String[] args) {
        String s = "string ";
        s += "is a good boy!";
        s += "really?";
    }
}

从下面的虚指令中可以看出,在往字符串s中添加新内容的时候,其过程在下面代码中注释。

[]$ javap -p -v StringTest
    Classfile /home/hadoop/zhdd/StringTest.class
      Last modified Dec 6, 2015; size 511 bytes
      MD5 checksum f960070f295b4e22de6bffe8f06634f4
      Compiled from "StringTest.java"
    public class StringTest
      SourceFile: "StringTest.java"
      minor version: 0
      major version: 51
      flags: ACC_PUBLIC, ACC_SUPER
    Constant pool:
       #1 = Methodref          #10.#19        //  java/lang/Object."<init>":()V
       #2 = String             #20            //  string 
       #3 = Class              #21            //  java/lang/StringBuilder
       #4 = Methodref          #3.#19         //  java/lang/StringBuilder."<init>":()V<
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值