从源码看String,StringBuffer,StringBuilder的区别
前言
看了一篇文章,大概是讲面试中的java基础的,有如题这么个面试题。我又翻了一些文章看了下,然后去看源码。看一下源码大概能更加了解一些。
String
String类是final的,表示不可被继承,不可变的。注释上也有说明:

其中用一个char[]来保存String的值。
private final char value[];
一旦赋值,就不可改变。看一下,操作string的源码,例如 substring,replace,concat 等方法,最终结果都是返回 new String(...). 也就是重新创建了一个String对象。
public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > value.length) {
throw new StringIndexOutOfBoundsException(endIndex);
}
int subLen = endIndex - beginIndex;
if (subLen < 0) {
throw new StringIndexOutOfBoundsException(subLen);
}
return ((beginIndex == 0) && (endIndex == value.length)) ? this
: new String(value, beginIndex, subLen);
}
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);
return new String(buf, true);
}
public String replace(char oldChar, char newChar) {
if (oldChar != newChar) {
int len = value.length;
int i = -1;
char[] val = value; /* avoid getfield opcode */
while (++i < len) {
if (val[i] == oldChar) {
break;
}
}
if (i < len) {
char buf[] = new char[len];
for (int j = 0; j < i; j++) {
buf[j] = val[j];
}
while (i < len) {
char c = val[i];
buf[i] = (c == oldChar) ? newChar : c;
i++;
}
return new String(buf, true);
}
}
return this;
}
StringBuffer 和 StringBuilder
它两个都是继承自 AbstractStringBuilder 抽象类,不同的是StringBuffer类都是带有 synchronized 关键字的。也就是说,StringBuffer是线程安全的,而 StringBuilder不是。他们中的方法基本上调用 super的方法。也就是AbstractStringBuilder 里实现的方法。
平时用的比较多的就是 append 方法。我们看一下代码实现:
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}
private void ensureCapacityInternal(int minimumCapacity) {
// 当append之后的长度大于当前value的长度的时候,需要重新生成一个char[]数组。
if (minimumCapacity - value.length > 0) {
value = Arrays.copyOf(value,
newCapacity(minimumCapacity));
}
}
public static char[] copyOf(char[] original, int newLength) {
//重新创建一个char[]数组
char[] copy = new char[newLength];
//将之前的值赋值到该数组中
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
ensureCapacityInternal 方法中,将 value的值重新扩展比如 str.append("abc")。假如之前value的值为:{'h','e','l','l','o'},当调用 str.getChars方法之后,会将 abc 追加到value数组后,value值就变成 :{'h','e','l','l','o','a','b','c'}
其实 getChars 方法只是做了一件事情 :System.arraycopy。
如图:

执行完arraycopy之后

总结
String 不可变,StringBuffer和StringBuilder可变,但是StringBuilder非线程安全。可以根据他们不同的特性分情况使用。
从源码看String,StringBuffer,StringBuilder的区别的更多相关文章
- String,StringBuffer,StringBuilder的区别及其源码分析
String,StringBuffer,StringBuilder的区别这个问题几乎是面试必问的题,这里做了一些总结: 1.先来分析一下这三个类之间的关系 乍一看它们都是用于处理字符串的java类,而 ...
- [置顶] String StringBuffer StringBuilder的区别剖析
这是一道很常见的面试题目,至少我遇到过String/StringBuffer/StringBuilder的区别:String是不可变的对象(final)类型,每一次对String对象的更改均是生成一个 ...
- 从源码看commit和commitAllowingStateLoss方法区别
Fragment介绍 在很久以前,也就是我刚开始写Android时(大约在2012年的冬天--),那时候如果要实现像下面微信一样的Tab切换页面,需要继承TabActivity,然后使用TabHost ...
- 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对象,其长度是固定的,内容 ...
- JDK源码分析-String、StringBuilder、StringBuffer
String类的申明 public final class String implements java.io.Serializable, Comparable<String>, Char ...
- 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.区别 可以从以下 ...
随机推荐
- python中的单例模式的应用
1 使用__new__方法 class Singleton(object): def __new__(cls, *args, **kw): if not hasattr(cls, ...
- Java API 之 正则表达式
一.基本概念 在项目中我们经常性做的一件事是“匹配”字符串 比如: 1.我们要验证用户输入的手机号是否合法? 2.验证设置的密码是否符合规则? 3.或者替换指定字符串中的一些内容. 这么一看,似乎正则 ...
- Java并发编程:volatile关键字解析(学习总结-海子)
博文地址:Java并发编程:volatile关键字解析
- PHP三维优先级运算
昨天去某大型公司面试,做了一套面试题,整套面试题的基础要求比较高,对于js的使用有一定的要求.在本次面试中碰到PHP三维运算优先级的问题,先看题: <?php $b=20; $c=40; $a= ...
- promose
function runAsync1(){ var p = new Promise(function(resolve, reject){ //做一些异步操作 setTimeout(function() ...
- PHPStorm-Mintfy-And-Color-Schema
美化Php-storm 1.隐藏一些工具条 打开一个项目后我习惯把一些工具条隐藏,在view菜单中把Tool buttons,Status bar,Navigation bar. CTRL+E 切换当 ...
- 浮动的补充丶文本和字体属性丶background丶定位
一丶浮动的补充 浮动的特性: 1. 浮动的元素脱标 2.浮动的元素互相贴靠 3.浮动的元素有"字围"效果 4.浮动的元素有收缩的效果 前提是标准文档流,margin的垂直方向会出现 ...
- php扩展库
php调用C/C++动态链接库 字数997 阅读28 评论0 喜欢0 本人最近在找实习,移动开发方向.有意者可直接与本人联系.谢谢! 一.简介 一般而言,php速度已经比较快,但是,对于一些较高级开发 ...
- arm汇编学习(三)
一.ndk编译android上运行的c程序 新建个hello目录,底下要有jni目录,下面就是Android.mk文件 1.Android.mk文件内容如下: LOCAL_PATH:= $(call ...
- IIS6.0配置正常,但是显示“网页无法访问”,Httperr.log中显示全是“Connections_refused”,问题总结
转自:http://blog.csdn.net/foxeatapple/article/details/21983869 最近部门的Web服务器突然无法访问! 加班解决! 问题症状: 1.“Inter ...