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 ...
随机推荐
- vue 自定义指令input表单的数据验证
一.代码 <template> <div class="check" > <h3>{{msg}}</h3> <div clas ...
- 使用 data-* 属性来嵌入自定义数据:
<!DOCTYPE html> <html> <head> <script> function showDetails(animal) { var an ...
- elasticsearch配置优化
调整ES内存分配有多种方式,建议调整 elasticsearch 中的设置(还可以直接修改bin下的启动脚本). # Directory where the Elasticsearch binary ...
- <爬虫>利用BeautifulSoup爬取百度百科虚拟人物资料存入Mysql数据库
网页情况: 代码: import requests from requests.exceptions import RequestException from bs4 import Beautiful ...
- badboy的录制和jmeter的使用
v Jmeter是什么 Apache Jmeter是Apache组织开发的基于Java的压力测试工具. Jmeter可以用于对服务器.网络或对象模拟巨大的负载,来自不同压力类别下测试它们的强度和分析 ...
- Linux文件句柄数配置
1.单程序句柄数限制 查看配置的句柄数:ulimit -n cat /etc/security/limits.conf 参考配置: * soft nofile 655360* hard nofile ...
- 设置苹果手机input按钮和button按钮颜色显示问题
网页上,尽管设置了input按钮和button的背景颜色,但在苹果手机上测试时仍会发现背景颜色为透明渐变色,不起作用,怎么解决呢? 在css公共样式中加上下面代码就可以解决,去除button和inpu ...
- Python-异常处理 使用selenium库自动爬取数据
异常处理 处理程序的报错 语法 捕捉万能异常: try: print(a) except Exception as e: print("你的代码有问题") print(" ...
- leyou_06_图片上传至FastDFS
1.推荐一个开源的FastDFS客户端,支持最新的SpringBoot2.0.配置使用极为简单,支持连接池,支持自动生成缩略图 1.1 在文件上传的微服务中 引入依赖 <dependency&g ...
- php filemtime filectime fileatime的区别
1.fileatime()int fileatime(string filename):fileatime()函数返回filename最后访问的时间,这里的最后访问是指每当一个文件的数据块被读取,采用 ...