深入源码剖析String,StringBuilder,StringBuffer
【String,StringBuffer,StringBulider】

深入源码剖析String,StringBuilder,StringBuffer
【作者:高瑞林】
【博客地址】http://www.cnblogs.com/grl214
| 写给读者的话 |
------亲爱的读者感谢您对小编的支持,当我正值青春的年纪里,很高兴能结识了一群花样年华的你们。当幸福像花儿一样盛开,请允许我记住在花季里始终如一关注我的你谢谢您一直在路上!让我们一起带着欢乐走进Java的世界!
| 目录 |
- 概述
- 从实际出发谈论String,StringBuffer,StringBuilder诞生背景
- 深入源码进行分析
- 总结
| 一.概述 |
首先聊一下String,String表示的是字符串,在String的源码中存在如下:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
由于字符串是由若干个字符线性组成,在java中所有的字符串都可以用数组的形式来存储,由于所声明的数组类型加了final,以至于String成为了一个不可变的字符序列,而在实际的问题中都存在需要字符串变动的情况,针对这一情况,引入了StringBuilder,和StringBuffer,其中StringBuilder是在jdk1.5之后增加的.
| 二.从实际出发谈论String,StringBuffer,StringBuilder诞生背景 |
在实际的编程应用,我们经常会涉及到对字符串的一个操作,例如:(增加,删除,截取,替换...),jdk1.0诞生那时的String类是一个封装字符串不可变的,所以在那时只能通过建立临时字符串变量,来对字符串进行增加,删除,截取,替换...,这样的做法使得我们操作的只是临时字符串,而真正的字符串却没有任何变动。既然String是封装不可变数组,那么也得有封装可变数组,就这样StringBuffer诞生了,而且还是线程安全的,由于这种线程安全的StringBuffer在非线程下效率很低,所有jdk1.5之后StringBuilder诞生了,StringBuilder是非线程安全可变字符串类,相比StringBuffer效率很高!
| 三.深入源码进行分析 |
1、StringBuilder和StringBuffer类的关键源码分析:
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
1 abstract class AbstractStringBuilder implements Appendable, CharSequence {
/**
* The value is used for character storage.
*/
2 char[] value;
从中可以看出StringBuilder和StringBuffer都继承抽象类AbstractStringBuilder ,所以AbstractStringBuilder 也是它俩共同的父类,并且在父类中声明的数组也是可变的。
2.StringBuilder和StringBuffer默认值问题
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{ /** use serialVersionUID for interoperability */
static final long serialVersionUID = 4383685877147921099L; /**
* Constructs a string builder with no characters in it and an
* initial capacity of 16 characters.
*/
public StringBuilder() {
super(16);
} /**
* Constructs a string builder with no characters in it and an
* initial capacity specified by the <code>capacity</code> argument.
*
* @param capacity the initial capacity.
* @throws NegativeArraySizeException if the <code>capacity</code>
* argument is less than <code>0</code>.
*/
public StringBuilder(int capacity) {
super(capacity);
}
从中可以看出,可变数组的长度大小默认是16,所以如果当长度的大小超过默认值,又会发生什么呢?请看下面代码:
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0)
//调用下面的expandCapacity方法实现“扩容”特性
expandCapacity(minimumCapacity);
}
/**
* This implements the expansion semantics of ensureCapacity with no
* size check or synchronization.
*/
void expandCapacity(int minimumCapacity) {
//“扩展”的数组长度是按“扩展”前数组长度的2倍再加上2 byte的规则来扩展
int newCapacity = value.length * 2 + 2;
if (newCapacity - minimumCapacity < 0)
newCapacity = minimumCapacity;
if (newCapacity < 0) {
if (minimumCapacity < 0) // overflow
throw new OutOfMemoryError();
newCapacity = Integer.MAX_VALUE;
}
//将value变量指向Arrays返回的新的char[]对象,从而达到“扩容”的特性
value = Arrays.copyOf(value, newCapacity);
}
从上述代码中可以看出当实际数组长度超过默认值时会自动进行扩容,具体是原有数组长度的两倍加2,再不够,再进行扩容!
| 四.总结 |
1.并不是任何情况下StringBuilder都一定比String效率高,例如:
效率:String>StringBuffer
String str="my"+"name"+"is";
StringBuffer Sb = new StringBuilder(“my”).append(“ name”).append(“ is”);
效率:StringBuffer>String
String S2 = “my name is”;
String S3 = “ gaoruilin”;
String S4 = “ test”;
String S1 = S2 +S3 + S4;
。。。。。。希望这次分享能给读者带来技术上的巩固,谢谢观看!
深入源码剖析String,StringBuilder,StringBuffer的更多相关文章
- String -- 从源码剖析String类
几乎所有的 Java 面试都是以 String 开始的,String 源码属于所有源码中最基础.最简单的一个,对 String 源码的理解也反应了你的 Java 基础功底. String 是如何实现的 ...
- JDK源码分析系列---String,StringBuilder,StringBuffer
JDK源码分析系列---String,StringBuilder,StringBuffer 1.String public final class String implements java.io. ...
- 从源码角度简单看StringBuilder和StringBuffer的异同
概述 StringBuilder和StringBuffer是两个容易混淆的概念,本文从源码入手,简单看二者的异同. 容易知道的是,这两者有一个是线程安全的,而且线程安全的那个效率低. java doc ...
- 基于mybatis-generator-core 1.3.5项目的修订版以及源码剖析
项目简单说明 mybatis-generator,是根据数据库表.字段反向生成实体类等代码文件.我在国庆时候,没事剖析了mybatis-generator-core源码,写了相当详细的中文注释,可以去 ...
- SpringMVC源码剖析(四)- DispatcherServlet请求转发的实现
SpringMVC完成初始化流程之后,就进入Servlet标准生命周期的第二个阶段,即“service”阶段.在“service”阶段中,每一次Http请求到来,容器都会启动一个请求线程,通过serv ...
- JDK源码学习--String篇(四) 终结篇
StringBuilder和StringBuffer 前面讲到String是不可变的,如果需要可变的字符串将如何使用和操作呢?JAVA提供了连个操作可变字符串的类,StringBuilder和Stri ...
- 转:【Java集合源码剖析】Hashtable源码剖析
转载请注明出处:http://blog.csdn.net/ns_code/article/details/36191279 Hashtable简介 Hashtable同样是基于哈希表实现的,同样每个元 ...
- C# Dictionary源码剖析---哈希处理冲突的方法有:开放定址法、再哈希法、链地址法、建立一个公共溢出区等
C# Dictionary源码剖析 参考:https://blog.csdn.net/exiaojiu/article/details/51252515 http://www.cnblogs.com/ ...
- 【Java集合源码剖析】Hashtable源码剖析
转载出处:http://blog.csdn.net/ns_code/article/details/36191279 Hashtable简介 Hashtable同样是基于哈希表实现的,同样每个元素是一 ...
随机推荐
- js验证IP及子网掩码的合法性
function checkIP(ip) { obj=ip; var exp=/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0 ...
- redis sets类型及操作
sets类型及操作set是集合,它是string类型的无序集合.通过hash table实现,添加.删除.查找的复杂度都是0(1).对集合我们可以实现取交际.差集并集.通过这些操作我们可以实现SNS中 ...
- doubango(6)--Doubango协议栈中对RTP的管理
相关数据结构 1. tsip_dialog_invite_t 描述: 一个invite_dialog代表了一个invite期间的所有的信令流程,因此,它首先是一个普遍的dialog的特殊化结构, ...
- java较全的面试题
一.Java基础部分 1. JAVA的基本数据类型有哪些 ? String 是不是基本数据类型 ? 2. 一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? ...
- Ubuntu下java环境的搭建
喜欢捣鼓计算机相关的,然后大二的时候就想着用linux,于是当时就装了个ubuntu,还想着把java环境搭建进去,但当时由于"意志不坚定"后来就没用linux了,知道最近突然想在 ...
- 自己开发轻量级ORM(二)
上一篇简单的对轻量级ORM开发开了个头.这篇主要聊下ORM框架的设计思路. ORM本质上是对数据库操作的抽象.大体上我将其分为对数据结构的抽象和对执行方法的抽象. 我的ORM设计图: ORM框架需要完 ...
- java系列笔记---正则表达式(2)
正则表达式 说真的正则表达式真不好写,当我收集资料准备开始写的时候,发现收集的东西越来越多范围也越来越广,我文章的前提就是文章要清晰, 在缕清自己思路之后,我从先简后难的方式来写有关正表达式,你们如果 ...
- struts2系列笔记(1)
struts2框架 如果你之前在MVC模式的时候一直都是通过servlet,获取和返回数据,那么现在开始学习struts2框架, Struts是一个实现MVC设计模式的优秀的框架.它的许多优点我就不说 ...
- UINavigationController实现全屏滑动返回功能
说明: UINavigationController默认在push出的控制器中都有边沿滑动返回功能,但是只能从屏幕左边滑才能返回,若从屏幕中间画并没有效果.下面实现全屏滑动功能. 探究: 系统默认能够 ...
- 安卓TCP通信
tCPServer.java 服务器的两个socket都没有关闭:s,ss.两个都是一直开启,然后数据才有显示 class tcpServer { public static void main(St ...