深入理解String、StringBuffer、StringBuilder区别和源码实现

StringBuilder的底层实现原理 为什么动态拼接字符串的时候推荐使用StringBuilder?它的底层是如何实现的可修改? 阅读详情

区别
1、String是常量,而StringBuilder,StringBuffer是变量,
2、StringBuffer 与 StringBuilder 中的方法和功能完全是等价的,
3、只是StringBuffer 中的方法大都采用了 synchronized 关键字进行修饰,因此是线程安全的,
而 StringBuilder 没有这个修饰,可以被认为是线程不安全的。
4、在单线程程序下,StringBuilder效率更快,因为它不需要加锁,不具备多线程安全
而StringBuffer则每次都需要判断锁,效率相对更低

JVM内部String+的实现
StringBuffer 始于 JDK 1.0
StringBuilder 始于 JDK 1.5
从 JDK 1.5 开始,带有字符串变量的连接操作(+),JVM 内部采用的是
StringBuilder 来实现的,而之前这个操作是采用 StringBuffer 实现的。

StringBuilder实现原理

StringBuilder类继承自AbstractStringBuilder抽象类,实现Serializable序列化接口和CharSequence接口。
在这里插入图片描述
AbstractStringBuilder抽象类实现Appendabel,CharSequence接口。
在这里插入图片描述
通过length()和capacity来获取对应的总容量和已经使用的容量
在这里插入图片描述

StringBuilder初始化及扩容机制
1.StringBuilder()的初始容量为16个字符,当该对象的实体存放的字符的长度大于16时,实体容量就自动增加。
2.StringBuilder(int size)可以指定分配给该对象的实体的初始容量参数为参数size指定的字符个数。当该对象的实体存放的字符序列的长度大于size个字符时,实体的容量就自动的增加。以便存放所增加的字符。
3.StringBuilder(String s)可以指定给对象的实体的初始容量为参数字符串s的长度额外再加16个字符。当该对象的实体存放的字符序列长度大于size个字符时,实体的容量自动的增加,以便存放所增加的字符。
在这里插入图片描述

扩容算法:
使用append()方法在字符串后面追加东西的时候,如果长度超过了该字符串存储空间大小了就需要进行扩容:构建新的存储空间更大的字符串,将旧的复制过去;
其具体的算法都是调用AbstractStringBuilder中的方法;
在这里插入图片描述
在这里插入图片描述

在进行字符串append添加的时候,会先计算添加后字符串大小,传入一个方法:ensureCapacityInternal 这个方法进行是否扩容的判断,需要扩容就调用newCapacity方法进行扩容
尝试将新容量扩为大小变成2倍+2 if 判断一下 容量如果不够,直接扩充到需要的容量大小。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

StringBuffer的实现原理
StringBuffer也是继承AbstractStringBuilder的,只是其在重写父类的方法的时候加上了synchronized关键字,使得StringBuffer的方法变成了线程安全的方法
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

String使用场景:

public static void main(String[] args) {  
        /** 
         * 情景一:字符串池 
         * JAVA虚拟机(JVM)中存在着一个字符串池,其中保存着很多String对象; 
         * 并且可以被共享使用,因此它提高了效率。 
         * 由于String类是final的,它的值一经创建就不可改变。 
         * 字符串池由String类维护,我们可以调用intern()方法来访问字符串池。  
         */  
        String s1 = "abc";     
        //↑ 在字符串池创建了一个对象  
        String s2 = "abc";     
        //↑ 字符串pool已经存在对象“abc”(共享),所以创建0个对象,累计创建一个对象  
        System.out.println("s1 == s2 : "+(s1==s2));    
        //↑ true 指向同一个对象,  
        System.out.println("s1.equals(s2) : " + (s1.equals(s2)));    
        //↑ true  值相等  
        //↑------------------------------------------------------over  
        /** 
         * 情景二:关于new String("") 
         *  
         */  
        String s3 = new String("abc");  
        //↑ 创建了两个对象,一个存放在字符串池中,一个存在与堆区中;  
        //↑ 还有一个对象引用s3存放在栈中  
        String s4 = new String("abc");  
        //↑ 字符串池中已经存在“abc”对象,所以只在堆中创建了一个对象  
        System.out.println("s3 == s4 : "+(s3==s4));  
        //↑false   s3和s4栈区的地址不同,指向堆区的不同地址;  
        System.out.println("s3.equals(s4) : "+(s3.equals(s4)));  
        //↑true  s3和s4的值相同  
        System.out.println("s1 == s3 : "+(s1==s3));  
        //↑false 存放的地区多不同,一个栈区,一个堆区  
        System.out.println("s1.equals(s3) : "+(s1.equals(s3)));  
        //↑true  值相同  
        //↑------------------------------------------------------over  
        /** 
         * 情景三:  
         * 由于常量的值在编译的时候就被确定(优化)了。 
         * 在这里,"ab"和"cd"都是常量,因此变量str3的值在编译时就可以确定。 
         * 这行代码编译后的效果等同于: String str3 = "abcd"; 
         */  
        String str1 = "ab" + "cd";  //1个对象  
        String str11 = "abcd";   
        System.out.println("str1 = str11 : "+ (str1 == str11));  
        //↑------------------------------------------------------over  
        /** 
         * 情景四:  
         * 局部变量str2,str3存储的是存储两个拘留字符串对象(intern字符串对象)的地址。 
         *  
         * 第三行代码原理(str2+str3): 
         * 运行期JVM首先会在堆中创建一个StringBuilder类, 
         * 同时用str2指向的拘留字符串对象完成初始化, 
         * 然后调用append方法完成对str3所指向的拘留字符串的合并, 
         * 接着调用StringBuilder的toString()方法在堆中创建一个String对象, 
         * 最后将刚生成的String对象的堆地址存放在局部变量str3中。 
         *  
         * 而str5存储的是字符串池中"abcd"所对应的拘留字符串对象的地址。 
         * str4与str5地址当然不一样了。 
         *  
         * 内存中实际上有五个字符串对象: 
         *       三个拘留字符串对象、一个String对象和一个StringBuilder对象。 
         */  
        String str2 = "ab";  //1个对象  
        String str3 = "cd";  //1个对象                                         
        String str4 = str2+str3;                                        
        String str5 = "abcd";    
        System.out.println("str4 = str5 : " + (str4==str5)); // false  
        //↑------------------------------------------------------over  
        /** 
         * 情景五: 
         *  JAVA编译器对string + 基本类型/常量 是当成常量表达式直接求值来优化的。 
         *  运行期的两个string相加,会产生新的对象的,存储在堆(heap)中 
         */  
        String str6 = "b";  
        String str7 = "a" + str6;  
        String str67 = "ab";  
        System.out.println("str7 = str67 : "+ (str7 == str67));  
        //↑str6为变量,在运行期才会被解析。  
        final String str8 = "b";  
        String str9 = "a" + str8;  
        String str89 = "ab";  
        System.out.println("str9 = str89 : "+ (str9 == str89));  
        //↑str8为常量变量,编译期会被优化  
        //↑------------------------------------------------------over  
    } 
StringBuilder原理分析(图文解析+代码源码注释) 文章目录StringBuilder原理分析 StringBuilder原理分析 阅读详情

相关推荐

String StringBuffer和StringBuilder区别之源码解析

String StringBuffer和StringBuilder 区别之源码解析 从源码角度简单对它们之间的区别进行了验证

StringBuilder原理

stringbuilder原理(自己的理解)欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。 新的改变 我们对Markdown编辑器进行了一些...

BIackMamba的博客 3304

源码string和stringbuffer

针对String的详细介绍针对String的详细介绍针对String的详细介绍针对String的详细介绍针对String的详细介绍针对String的详细介绍针对String的详细介绍针对String的详细介绍针对String的详细介绍针对String的详细介绍针对String的详细介绍针对String的详细介绍

Java 中的 StringBuilder :原理、用法与源码解析

StringBuilder是Java中用于高效字符串拼接的可变字符序列。相比String的不可变性,StringBuilder直接在原对象上修改,避免频繁创建临时对象,提升性能。其核心实现基于可变char数组,支持append、insert、delete等操作,默认扩容策略为翻倍+2。StringBuilder线程不安全但性能高,适合单线程场景;多线程应使用StringBuffer。优化建议包括:预估容量减少扩容、链式调用、批量操作等。理解其底层实现有助于编写更高效的字符串处理代码。

2503_93067241的博客 792

STM32智能头盔DIY全攻略:从心率监测到跌倒报警的完整实现

本文提供了基于STM32的智能头盔完整DIY实现方案,涵盖从心率监测到跌倒报警的核心功能。详细解析了系统设计、硬件搭建、软件算法及系统联调,重点介绍了STM32主控、MAX30102心率传感器和MPU6050姿态传感器的应用,并分享了跌倒检测算法与功耗优化等实战经验,为嵌入式开发与物联网创新项目提供全面指导。

sony5的博客 500

从‘最速控制’到代码:深入拆解韩京清ADRC中TD跟踪器的fhan函数(含Matlab/Simulink实例)

本文深入解析韩京清ADRC中的fhan函数,从理论到代码实现,详细拆解其在Matlab/Simulink中的应用。通过分析最速控制问题和非线性TD的连续形式,揭示fhan函数在信号处理和噪声抑制中的独特优势,并提供工程实践中的参数整定和优化技巧。

weixin_42659194的博客 247

深入理解StringBuilder类

在学习String类时,API中说字符串缓冲区支持可变的字符串,什么是字符串缓冲区呢?接下来研究下字符串缓冲区。查阅StringBuilder的API,StringBuilder又称为可变字符序列,它是一个类似于 String 的字符串缓冲区,通过某些方法调用可以改变该序列的长度和内容。原来StringBuilder是个字符串的缓冲区,即它是一个容器,容器中可以装很多字符串。并且能够对其中的字符串进行各种操作。

2301_77206753的博客 4012

AI数字人:口播与唇形同步的福音,支持本地部署/批量生成/口齿清晰

你也可以直接输入语音,虚拟化身会根据语音的节奏和语调,同步做出相应的动作和表情,表现更加生动。不过这依然是个值得关注的工具。借助先进的 AI 算法,Heygem 高精度捕捉五官、轮廓等特征,构建逼真的虚拟模型。同时,它还能克隆语音,捕捉人声的细微特征,支持多种语音参数设置,打造高度相似的音色效果。打开设置,调整镜像存储位置,镜像文件比较大70~80G,选择合适的盘,设置完成后点击“Apply & Restart”。数字人视频画面与声音高度同步,口型匹配自然流畅,智能优化音视频效果,带来极佳的视听体验。

m0_72580657的博客 5862

String源码深度剖析(面试题剖析)

1.1 final String类被final关键字修饰,不能被继承,赋值后不可修改。java.io.Serializable:详解序列化接口,标记接口(Marker Interface),实现了标记接口的类仅仅是给自身贴了个”标记“,未实现该接口无法被序列化。Comparable比较器,值提供一个compareTo方法,用于比较两个字符串大小,下面会讲解该方法。CharSequenceCharSequence是字符值的可读序列。此接口提供对多种不同类型的字符序列的统一只读访问。查看String源码我们可以

莫安逸无风雪 1007

ENVI遥感技术

记录2024.03.06所遇到的遥感问题

qq_44453923的博客 4332

YOLO26改进策略【卷积层】| DWRSeg :高效获取多尺度上下文信息,二次改进C3k2

本文记录的是利用DWR 模块改进 YOLO26 的特征提取部分。(Dilation-wise Residual)通过两步残差流程(区域残差化-语义残差化)与分支化空洞卷积结合,引导解码器处理特征与跳接特征的多尺度精准融合。本文利用模块,通过区域残差化生成简洁区域型特征图以简化融合基础,再通过分支化空洞卷积捕捉多尺度空间上下文,同时依托残差连接保留原始特征信息,对YOLO26中不同尺度目标特征进行针对性强化、抑制无效背景特征干扰,在特征融合阶段实现多尺度语义与细节信息的高效互补,避免传统多感受野卷积的冗余计算

Limiiiing的博客 159

java string 分析_Java String的相关性质分析

引言String可以说是在Java开发中必不可缺的一种类,String容易忽略的细节也很多,对String的了解程度也反映了一个Java程序员的基本功。下面就由一个面试题来引出对String的剖析。1. String在源码里究竟是如何实现的,它有哪些方法,有什么作用?从源码可以看出,String有三个私有方法,底层是由字符数组来存储字符串public final class Stringimple...

weixin_36378669的博客 182

Android 中 app freezer 原理详解(二):S 版本

在之前的两篇博文《Android 中app内存回收优化(一)》和《Android 中app内存回收优化(二)》中详细剖析了 Android 中 app 内存优化的流程。这个机制的管理通过 CachedAppOptimizer 类管理,为什么叫这个名字,而不叫 AppCompact 等?freezer,一个针对应用进程长期处于 Cached 状态的优化。在之前博文《app freezer 原理 R 版本》

私房菜 3610

Java String常见面试题汇总

String类型的面试题 1.       String是最基本的数据类型吗? 基本数据类型包括byte,int,char,long,float,double,boolean,short一共八个. Java.lang.String类是final类型的,因此不能继承,修改这个类.为了提高效率节省空间,应该用StringBuffer类. 2.       Str

Leeon的博客 2300

uniapp H5刷新页面后返回按钮失效问题完美解决方案

这个问题其实很隐蔽,尤其是uniapp H5 场景下刷新导致栈清理,很多开发者一开始都懵掉了。uniapp 内部对「页面栈只有一个」时的返回逻辑是reLaunch;所以只要在这个分支里替换为自己的逻辑(比如),就能顺利实现预期。目前我在项目里已经跑通了,暂时没发现问题。不得不说,知道源码里这个逻辑后,真的是醍醐灌顶,只能膜拜框架大佬了 🤯。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 524

全国青少年信息素养大赛图形化(Scratch)编程考点总结

全国青少年信息素养大赛图形化(Scratch)编程考点总结

伶俐角少儿编程 382

目录(面试总结)

序号 内容 1 SpringBoot自动配置原理 2 SpringBoot自动配置原理(源码跟踪) 3 如何自定义starter

2301_77196103的博客 119

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

学习java第三周

本周学习的内容并不是特别多,前面的基础基本都学习完了,本周尝试着开始看源码,了解Java语言中源码的作用。所以说时间占用比较大。 1.对String有了更深刻,更透彻的了解。 String 为不可变字符串,通过原码发现,前面有final进行修饰,所以说不可变 这一点与c++当中我们学习的string还是有所不同的,通过一个小例子我们可以很简单的比较出来。 例如Stringstr1="hello"+"java"相当于str1=“hellojava” Stringstr2="hellojav...

ZzxSdauu的博客 249

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Java进阶之深入理解String/StringBuffer与StringBuilder

1 String、StringBuffer与StringBuilder区别 (1)区别 String内容不可变,StringBuffer和StringBuilder内容可变; StringBuilder非线程安全(单线程使用),String与StringBuffer线程安全(多线程使用); 如果程序不是多线程的,那么使用StringBuilder效率高于StringBuffer。 (2)...

chenliguan的博客 1万+

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

通过源码分析String、StringBuffer和StringBuilder

0x00 简介又翻出来了在15年整理的笔记了。感觉当初还是挺较真的。自己对String的理解总是存在着不同程度的误差,经常处于一知半解的状态,而且对其内部的原理也不是特别清楚,碰巧又和同学聊起这个知识点,秉承爱折腾的原则,在论文答辩之际详细整理一下。0x01 说明最初听说的String、StringBuffer和StringBuilder三者之间的区别主要是下面这个版本(略作总结): String:

木东居士 930

【JavaSE】面试高频String、StringBuffer、 StringBuilder坑点总结刨析

String对象在内存中的存在形式?String为啥是不可变的?三大字符串究竟有什么区别?本文对StringBuffer,StringBuilder,String横向对比并深入源码进行刨析总结。

黄小黄的博客 1150

String、StringBuilder、StringBuffer

String、StringBuilder、StringBuffer

pig_ning的博客 588

String、StringBuffer与StringBuilder之间区别

String、StringBuffer与StringBuilder之间区别 分析一: 记住一点,String类型字符串一旦被创建,就不能被更改。 String str =new String("Hello"); str=str+"word&a

null 1529

深入理解String、StringBuffer 和 StringBuilder类的区别

String(JDK1.0):不可变字符序列StringBuffer(JDK1.0):可变字符序列、效率低、线程安全StringBuilder(JDK 5.0):可变字符序列、效率高、线程不安全注意:作为参数传递的话,方法内部String不会改变其值,StringBuffer和StringBuilder会改变其值。深入理解String、StringBuffer和StringBuilder类的区别 - 腾讯云开发者社区-腾讯云 (tencent.com)...

小鲁蛋的博客 473

String、String.intern()方法、StringBuilder和StringBuffer的深入理解与总结

文章目录一、String类的一些基础知识和要点1. String类和字符数组是被fianl修饰的2. String类中字符串的操作方法返回的都是新对象二、String的不同创建方式的以及intern()方法的深入理解1. String的不同创建方式1.1 小结(重要)2. String对象中字面量+字面量和字面量+常量的不同3. intern()方法的作用3.1 inten()在JDK1.6和JD...

超级无敌小胖头 932

JavaSE09:String、StringBuffer、StringBuilder底层源码解析(纯干货)

带你深入了解字符串类的结构!

deserts的博客 638
上一篇: 编译型语言、解释型语言、静态类型语言、动态类型语言概念与区别
下一篇: finally一定会被执行么?
DanLongChen
博客等级 码龄9年 13粉丝 54原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值