Java问题解读系列之String相关---String、StringBuffer、StringBuilder的区别
今天的题目是String、StringBuffer和StringBuilder的区别:
首先还是去官方的API看看对这三种类型的介绍吧,Go......
一、继承类和实现接口情况
1、String类
public final class String
extends Object
implements Serializable, Comparable<String>, CharSequence
2、StringBuffer类
public final class StringBuffer
extend Object
implements Serializable, CharSequence
3、StringBuilder类
public final class StringBuilder
extends Object
implements Serializable, CharSequence
由以上三段代码可以看出:
它们都继承自Object类,并且实现了Serializable, CharSequence这两个接口,而String比另外两个多实现了一个用来比较字符串是否相等的接口Comparable
二、官方解释
1、String类

2、StringBuffer类

3、StringBuilder类

其实从以上官方解释中,我只能理解以下几点:
(1)String定义的字符串是不能被改变的;而StringBuffer和StringBuilder定义的字符串本身不能被改变,但可以通过调用一些方法来改变(其实不太理解)
(2)String和StringBuffer操作字符串是线程安全的;而StringBuilder线程不安全;
(3)它们的效率从高到底依次为StringBuilder>StringBuffer>String
但是还有一个根本的问题需要弄清楚-----“不能被改变”到底是什么意思?比如下面这段代码:
String str1 = "Hello";
str1+=" World";
System.out.println(str1); 答案是:Hello World
运行完上面这段代码,我就很疑惑,不是说不能被改变吗,为什么改变之后却没有报错?经过一番调研之后发现,这里就存在一个java内存分配机制的问题,这里面所说的改变指的是对同一个字符串内容的改变,虽然上面的代码看上去是改变了str的内容,其实却不然,理解了内存分配就知道是怎么回事了。于是我又去了解了一下java内存分配机制问题:
Java栈、堆、常量池、方法区
1、 栈。栈中存放的是一些基本类型的变量、变量值和一些引用变量。当在一段代码中定义一个变量时,java就在栈中为这个变量分配内存空间,在该变量退出作用域后会自动释放变量所占的内存空间供其他变量使用。
2、 堆。堆内存放一些由new关键字创建的对象和数组。堆中分配的内存,由java虚拟机的垃圾回收机制管理。我们使用new创建变量和对象时,都会给他们起一个名字,而这些名字是存放在栈中的。所以当堆中生成一个变量或数组时,它们的名字会被存放在栈中,名字所在的栈内存中存放的是指向变量或数组在堆内存中的首地址,这样我们就可以通过栈来找到堆中的数组或变量。存放在栈中的变量相当于堆内存中对象或数组的引用,称之为对象引用,即java中的指针。
Java中的堆内存是在程序运行过程中动态分配的,而且由java垃圾回收机制管理,当堆中的数据不被使用的时候回收内存。因为是动态分配所以读取速度比较慢,而且整个内存中只有一个堆被所有线程共享。
3、 方法区。方法区跟堆一样,被所有线程共享。用来存放一些常量、类信息、方法名和即时编译后的代码
4、 常量池。常量池指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据顾名思义,常量池中用来存放常量,如基本类型的值,对象型的常量值等。对于String类型,它的值就存放在常量池中,而jvm中的常量池是以表的形式存储的,对于string类型,有一张固定长度的表存储字符串的值,在程序执行的时候,常量池是存放在方法区,而不是堆中的。
看完内存分配机制,其实可以这样来理解前面那段代码的内存分配问题:

可以看出,我们定义的str是hello,虽然最后输出的是hello world,但是常量str="hello"并没有被改变,而是对新的字符串重新分配了一块内存空间。其实字符串不能被改变可以理解为变量的内存地址没有被改变,再来看下面的代码:
String string1 = "name";
String string2 = "name";
System.out.println(string1==string2);//true String string3 = new String("name");
String string4 = new String("name");
System.out.println(string3==string4);//false
string1和string2是存放在常量池中的,当创建string2时,常量池中已经有了name,所以string1指向name,不会重新创建一个一模一样的;
string3和string4是对象的引用,存放在栈中,实际的对象存在堆中,栈中的内存地址是不一样的,所以string3==string4为false
综上所述,String、StringBuffer和StringBuilder的区别如下(引自其它文章):

关于内存分配,目前觉得最好的一篇文章是:http://blog.csdn.net/yangyuankp/article/details/7651251
里面有四个链接,都很有价值,认真阅读完,相信会对java内存分配机制不再困惑。
以上是今天的所有内容......
Java问题解读系列之String相关---String、StringBuffer、StringBuilder的区别的更多相关文章
- Java问题解读系列之基础相关---含继承时的执行顺序
今天来研究一下含继承.静态成员.非静态成员时Java程序的执行顺序: 一.不含继承,含有静态变量.静态代码块 创建一个子类,该类包含静态变量.静态代码块.静态方法.构造方法 /** * @create ...
- Java问题解读系列之基础相关---抽象类和接口
今天来说一波自己对Java中抽象类和接口的理解,含参考内容: 一.抽象类 1.定义: public abstract class 类名{} Java语言中所有的对象都是用类来进行描述,但是并不是所有的 ...
- Java问题解读系列之IO相关---Java深拷贝和浅拷贝
前几天和棒棒童鞋讨论Java(TA学的是C++)的时候,他提到一个浅拷贝和深拷贝的问题,当时的我一脸懵圈,感觉自己学Java居然不知道这个知识点,于是今天研究了一番Java中的浅拷贝和深拷贝,下面来做 ...
- Java问题解读系列之String相关---String类为什么是final的?
今天看到一篇名为<Java开发岗位面试题归类汇总>的博客,戳进去看了一下题目,觉得有必要夯实一下基本功了,所以打算边学边以博客的形式归纳总结,每天一道题, 并将该计划称为java问题解读系 ...
- String,StringBuffer,StringBuilder的区别
public static void main(String[] args) { String str = new String("hello...."); StringBuffe ...
- [置顶] String StringBuffer StringBuilder的区别剖析
这是一道很常见的面试题目,至少我遇到过String/StringBuffer/StringBuilder的区别:String是不可变的对象(final)类型,每一次对String对象的更改均是生成一个 ...
- String,StringBuffer,StringBuilder的区别及其源码分析
String,StringBuffer,StringBuilder的区别这个问题几乎是面试必问的题,这里做了一些总结: 1.先来分析一下这三个类之间的关系 乍一看它们都是用于处理字符串的java类,而 ...
- Question 20171115 String&&StringBuffer&&StringBuilder的区别与联系?
Question 20171114 String&&StringBuffer&&StringBuilder的区别和联系 创建成功的String对象,其长度是固定的,内容 ...
- java常见面试题03-String,StringBuffer,StringBuilder的区别
面试题 A:String,StringBuffer,StringBuilder的区别 1:String 内容不可变,StringBuffer.StringBudiler可变 2:StringBu ...
随机推荐
- python中字符串的处理总结
在爬取新浪财经7*24直播中, 遇到了Unicode编码中文转utf-8的问题, 采用如下代码可以实现转化 >>> a='\\u76d1\\u7ba1\\u5bf929' >& ...
- 2016.10.29初中部上午NOIP普及组比赛总结
2016.10.29[初中部 NOIP普及组 ]模拟赛 做得好爽! 进度: 比赛:35+45+AC+0=180 改题:AC+AC+AC+0=300 幸运的数 有点无语--之前怕超限,还特意利用程序打了 ...
- Docker系列(十):Kubernetes集群入门
kubenetes安装 官网:https://github.com/kubernetes/kubernetes/blob/release-1.0/docs/getting-started- guide ...
- Python学习day01 - 计算机基础
第一天 什么是编程 语言就是用来交流的. 语言+火构成了人类的文明 Python语言用来和计算机交流 通过他和计算机交流,然后完成很多程序员想要完成的事情,就叫编程. 为什么要编程 节省劳动力,更高效 ...
- 使用RequestsCookieJar自动保存并传递cookie
使用python的requests开发爬虫程序的时候,经常需要将之前请求返回的cookie值作为下一个请求的cookie进行调用,比如模拟登录之后的返回的sessionID,就是需要作为后续请求的co ...
- yii2下使用支付宝
最近入坑了yii2 感觉是个很强大的框架.使用yii做支付宝的移动支付的时候出了点问题,记录下来避免以后忘记了. 使用的是支付宝立即到账的功能,网上很多集成好的接口我就不重复了,找不到的话github ...
- eclipse下项目复制改名注意事项
当在Eclipse下复制Web工程时 1.需要修改复制后新工程源码文件下 .settings 文件夹下的org.eclipse.wst.common.component中的内容为本工程名,明细如图:
- Python快速搭建HTTP服务器
<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style=&q ...
- 第一个入驻阿里云自营心选商城,如今它已经是营收过亿的SaaS独角兽
淘宝心选.网易严选.小米有品...越来越多的企业电商自有品牌围绕“低价好物”大做文章,用创新赢得了市场.作为To B从业人员,不由思考:C端的成功是否可以复制在B端? 伴随着互联网下半场的到来,云计算 ...
- Mybatis框架+原理
https://www.cnblogs.com/luoxn28/p/6417892.html(转载,蛮详细的)