String,StringBuffer,StringBuilder的区别及其源码分析
String,StringBuffer,StringBuilder的区别这个问题几乎是面试必问的题,这里做了一些总结:
1.先来分析一下这三个类之间的关系
乍一看它们都是用于处理字符串的java类,而且长得也都差不多,相信肯定有人会以为StringBuffer和StringBuilder都是继承自String这个类,即认为String类是其他两个类的超类。这种想法似乎很合理,但其实是不对的,事实上StringBuffer和StringBuilder确实是继承自某个类,但是这个类并不是String,至于是哪个类呢?我i们来看一下JDK源码:
StringBuffer类部分源码
StringBuilder类部分源码
String类部分源码
看到这里,这三个类的关系基本清晰:StringBuffer和StringBuilder都继承自AbstractStringBuilder这个类,而AbstractStringBuilder和String都继承自Object这个类(Object是所有java类的超类)。所以这三个类之间的关系可以大致表示为:
关于AbstractStringBuilder这个类,本人只在JDK1.8中的java.lang包下找到了,而在JDK1.6和JDK1.7中均未找到,似乎是1.8版本新加上去的,各位看官可以试着找找。
2.String是不可变类,而StringBuffer, StringBuilder是可变类
我们查看这三个类的源码,发现String类没有append(),delete(),insert()这三个成员方法,而StringBuffer,StringBuilder都有这些方法,这就很容易理解了(这里就不粘代码了,大家可以找源码看看)。所以我们可以归纳如下:
String —— 字符串常量;
StringBuffer —— 字符串变量;
StringBuilder —— 字符串变量。
3.再来说一下执行速度
在执行速度上,String < StringBuffer < Stringbuilder 。
3.1 String < StringBuffer
这是因为String类是不可变的,即字符串常量,所以每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象。这就会对程序运行产生很大的影响,因为当内存中的无引用对象多了以后,JVM的GC进程就会进行垃圾回收,这个过程会耗费很长一段时间,因此经常改变内容的字符串最好不要用 String类的对象。而如果是使用 StringBuffer 类则结果就不一样了,每次结果都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,再改变对象引用。所以在一般情况下我们推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。
但是在某些特殊情况下, String 对象的字符串拼接其实是被 JVM 解释成了 StringBuffer 对象的拼接,所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,而特别是以下的字符串对象生成中, String 运行速度是远要比 StringBuffer 快的:
但是如果要拼接的字符串来自于不同的String对象的话,那结果就不一样了:
这时候使用StringBuffer的运行速度更快,而这是我们编程时的大部分情况。
3.2 StringBuffer < Stringbuilder
这个结论的原因涉及到线程安全和非线程安全,将在下一节详细介绍。
String,StringBuffer,StringBuilder的区别及其源码分析的更多相关文章
- [置顶] String StringBuffer StringBuilder的区别剖析
这是一道很常见的面试题目,至少我遇到过String/StringBuffer/StringBuilder的区别:String是不可变的对象(final)类型,每一次对String对象的更改均是生成一个 ...
- String,StringBuffer,StringBuilder的区别
public static void main(String[] args) { String str = new String("hello...."); StringBuffe ...
- Question 20171115 String&&StringBuffer&&StringBuilder的区别与联系?
Question 20171114 String&&StringBuffer&&StringBuilder的区别和联系 创建成功的String对象,其长度是固定的,内容 ...
- java中 String StringBuffer StringBuilder的区别
* String类是不可变类,只要对String进行修改,都会导致新的对象生成. * StringBuffer和StringBuilder都是可变类,任何对字符串的改变都不会产生新的对象. 在实际使用 ...
- 深入理解String, StringBuffer, StringBuilder的区别(基于JDK1.8)
String.StringBuffer.StringBuilder都是JAVA中常用的字符串操作类,对于他们的区别大家也都能耳熟能详,但底层到底是怎样实现的呢?今天就再深入分析下这三种字符串操作的区别 ...
- Android/Java 中的 String, StringBuffer, StringBuilder的区别和使用
Android 中的 String, StringBuffer 和 StringBuilder 是移动手机开发中经常使用到的字符串类.做为基础知识是必须要理解的,这里做一些总结. A.区别 可以从以下 ...
- 在JAVA中,String,Stringbuffer,StringBuilder 的区别
首先是,String,StringBuffer的区别 两者的主要却别有两方面,第一是线程安全方面,第二是效率方面 线程安全方面: String 不是线程安全的,这意味着在不同线程共享一个String ...
- 从源码看String,StringBuffer,StringBuilder的区别
前言 看了一篇文章,大概是讲面试中的java基础的,有如题这么个面试题.我又翻了一些文章看了下,然后去看源码.看一下源码大概能更加了解一些. String String类是final的,表示不可被继承 ...
- String,StringBuffer,StringBuilder三者区别
String:每次改变,String都会重新构造,内存指针都会改变 StringBuffer:主要用在全局变量中 StringBuilder:在线程内完成字符拼接,因为线程是不安全的,所以完成后可以丢 ...
随机推荐
- 【Java学习笔记之二十八】深入了解Java8新特性
前言: Java8 已经发布很久了,很多报道表明java8 是一次重大的版本升级.在Java Code Geeks上已经有很多介绍Java 8新特性的文章,例如Playing with Java 8 ...
- 【VMware Workstation】虚拟机动态IP NAT连接外部网络(局域网以及广域网)
由于公司办公使用的账号认证获得IP,在虚拟机使用原来的桥接模式无法连接外网,因而需要更换虚拟机的网络连接方式. 虚拟机软件:VMware Workstation 12 Pro 虚拟机:centos7 ...
- ASP.NET Core 运行原理解剖[2]:Hosting补充之配置介绍
在上一章中,我们介绍了 ASP.NET Core 的启动过程,主要是对 WebHost 源码的探索.而本文则是对上文的一个补充,更加偏向于实战,详细的介绍一下我们在实际开发中需要对 Hosting 做 ...
- 匿名委托与Lambda表达式
通过使用匿名委托(匿名方法),使编程变得更加灵活,有关委托与匿名委托请参考我的前一篇Blog<委托与匿名委托>. 继续之前示例,代码如下: static void Main(string[ ...
- Java GUI学习心得
虽然GUI的应用已经不是特别广泛了,但是如果了解一点,可以做些自己想要的工具,最近做了一个工具(是什么就不提了),当然碰到很多的问题,都意义解决了,现在分享出来. 1.关于窗体面板的显示问题 可能会遇 ...
- 一位资深程序员大牛给予Java提升技术的学习路线建议
15套java架构师.集群.高可用.高可扩 展.高性能.高并发.性能优化.Spring boot.Redis.ActiveMQ.Nginx.Mycat.Netty.Jvm大型分布 式项目实战视频教程 ...
- Android Studio的Terminal配置
1.首先检查你的setting设置如下图 2.如果是已经ok的,请在你的Android sdk的文件夹目录下找到adb.exe,并配置环境变量 3.重启as,在terminal内输入 -adb hel ...
- web安全普及:通俗易懂,如何让网站变得更安全?以实例来讲述网站入侵原理及防护。
本篇以我自己的网站[http://www.1996v.com]为例来通俗易懂的讲述如何防止网站被入侵,如何让网站更安全. 要想足够安全,首先得知道其中的道理. 本文例子通俗易懂,从"破解网站 ...
- 极化码的matlab仿真(2)——编码
第二篇我们来介绍一下极化码的编码. 首先为了方便进行编码,我们需要进行数组的定义 signal = randi([0,1],1,ST); %信息位比特,随机二进制数 frozen = zeros(1, ...
- 《个人-GIT使用方法》
使用GIT版本控制工具及基本使用方法(安装,新建,推送,拉取),托管平台的使用方法. Git 常用命令 git init here -- 创建本地仓库(repository),将会在文件夹下创建一个 ...