【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同样是基于哈希表实现的,同样每个元素是一 ...
随机推荐
-
java16 程序、进程、线程
一.程序.进程.线程 .程序:程序就是我们编写的代码,也就是指令集,是一个静态概念. .进程:操作系统调度我们的程序,动态概念,一个程序就是一个进程.进程是程序的一次动态执行过程,占用特定的地址空间, ...
-
js鼠标移入移出事件会被子元素触发解决方法
问题:js写了一个鼠标移入移出事件,但是发现会被内部子元素不断的触发 解决方法:建立一个空的div定位到需要触发的位置,然后设置大小和触发范围一样,最后将事件写在空的div上.
-
【转】CefSharp语言(Locales)本地化问题
CefSharp默认是嵌入的chrome浏览器内核,默认英文,所以右键菜单以及一些功能都是英文显示. 国内用需要汉化.CefSharp本身支持本地化Locales,需要在初始化Browser的时候设置 ...
-
C# 实现身份验证之WebApi篇
今天再来总结关于如何实现WebApi的身份验证,以完成该系列所有文章,WebApi常见的实现方式有:FORM身份验证.集成WINDOWS验证.Basic基础认证.Digest摘要认证 第一种:FOR ...
-
amin例子的简单研究
amin这个例子,使用了比较复杂高阶的qml技巧,但是也有局限性.下面分3个部分,分别是界面部分,算法部分和扩展部分,简单地对这个问题进行理解. 由衷感谢:http://amin-ahm ...
-
mysql 触发器 trigger用法 one (简单的)
实例~~ example1: 创建表tab1 1 2 3 4 DROP TABLE IF EXISTS tab1; CREATE TABLE tab1( tab1_id varchar(11) ...
-
JSP 日期处理
JSP 日期处理 使用JSP最重要的优势之一,就是可以使用所有Java API.本章将会详细地讲述Java中的Date类,它在java.util包下,封装了当前日期和时间. Date类有两个构造函数. ...
-
20155319《Java程序设计》实验三(敏捷开发与XP实践)实验报告
20155319<Java程序设计>实验三(敏捷开发与XP实践)实验报告 一.实验内容及步骤 (一)使用Code菜单 在IDEA中使用工具(Code->Reformate Code) ...
-
Rooks---LightOj1005(排列组合)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1005 题意就是在一个n*n的方格中放k个棋子,每一行每一列都不能有两个棋子,问有多少种 ...
-
【转】【备忘录】MySQL性能优化的21个最佳实践 和 mysql使用索引
今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我 们程序员需要去关注的事情.当我们去设计数据库表结构,对操作数 ...