String、StringBuffer、StringBuilder的区别?

String在实例化之后,其内存空间的内容大小是不能够被修改的;而StringBuffer是一个线程安全的可变字符序列,在实例化之后可以动态的修改堆内存中的内容,所以内存长度和大小是可变的;StringBuilder实例化之后内存大小长度也是可变的,不同之处在于StringBuilder不是线程同步,因此操作起来必然比StringBuffer更加高效。

String、StringBuffer的区别?

它们都可以存储和操作字符串。

String类是字符串常量,是不可更改的。

StringBuffer是字符串变量,它的对象是可以扩充和修改的。

为什么String类的值是常量,但内容可以修改?

public class Test {
 public static void main(String[] args) {		
  String str="aaa";
  str+="bbb";
  System.out.println(str); 
 }
}

这里str的实体是”aaa”,已经不能变了,但对它进行“+=”操作修改变为了”aaabbb”,这不就是改变了吗?

其实不然,这里陷入了一个误区,就是 str+”bbb” 不是扩展,而是重新开辟空间

上面的例子中,str在栈区相当于一个指针,其实体首先为”aaa”,”aaa”在堆区是一个常量 “bbb”也是一个常量在堆区,

“aaa”+”bbb”这个操作不是在”aaa”所在内存区域的后面插入”bbb”,而是重新创建一段空间,再把”aaa”和”bbb”都放进来

所以str+=”bbb” 实际上是str指向了新创建的”aaabbb”内存的区域,而以前的”aaa”、”bbb”两个空间还保留,等待JVM的垃圾回收程序GC回收。

所以说String类的对象的内容不可更改,但可以更改的是对象的引用。 字符串 String类之间使用’+’来操作是重新分配空间,而不是扩展。
再看个String的例子:

public class TestString {
 
 public static void main(String[] args){
  String a = "hello";
  String b = "hello";
  String c = new String("hello");
  String d = new String();
  d = "hello";
  String e = c;
  
  System.out.println("a==b ? " + (a== b));
  System.out.println("a==c ? " + (c== b));
  System.out.println("a==d ? " + (a== d));
  System.out.println("a==e ? " + (a== e));
  System.out.println("c==d ? " + (c== d));
  System.out.println("c==e ? " + (c== e));
 }
}

其中只有a==b==d 、 c=e。
解释:

1、String每new一次堆内存都不想等,而d在new分配完新地址之后,又放弃new之后的地址,指向a对应的内存地址,所以他们是相同的。

2、“hello”赋值这种直接赋值方式指向的堆内存空间是一样的。String在Java中使用了共享设计,在Java形成一个对象池,这个对象池可以保存多个对象,如果新实例化的对象已经在对象池中存在,就不在重复定义,直接从对象池中取出使用。所  以对于已存在的内容时,会将对象指向已经实例的空间地址。

3、e直接指向C的内存空间。

4、所以在使用String时,建议使用直接赋值方式,减小内存空间,提高性能。

String、StringBuffer和StringBuilder的区别

1、 String、StringBuffer、StringBuilder都是被final修饰的,是不能够被继承改写的。

2、 String在实例化之后,其内存空间的内容大小是不能够被修改的;而StringBuffer是一个线程安全的可变字符序列,在实例化之后可以动态的修改堆内存中的内容,所以内存长度和大小是可变的;StringBuilder实例化之后内存大小长度也是可变的,不同之处在于StringBuilder不是线程同步,因此操作起来必然比StringBuffer更加高效。

会有人想:

String str="hello";    
str="andy";

str的值不是也改变了吗?

其实上述代码在内存中已经开辟了3个空间,分别是:”hello“, ”andy“, ”helloandy“,他们的堆内存大小是固定的,最终str指向了”helloandy“的堆地址。如下图所示:

String、StringBuffer、StringBuilder的区别?

我们知道,String类对象的引用值可以改变,也就是说虽然str的内容不能改变,但是可以改变引用的值,使这个对象指向其他字符串常量。

而StringBuffer使用时,只会开辟一块内存空间,可以使用append添加delete等操作内容。

String 每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的。   而如果是使用   StringBuffer/StringBuilder 类则结果就不一样了,每次结果都会对 StringBuffer/StringBuilder 对象本身进行操作,而不是生成 新的对象,再改变对象引用。

因而在对一个字符串循环赋值时,最好使用StringBuffer(线程安全)或StringBuilder,这样可以节约内存,提高性能,切记。

125jz网原创文章。发布者:江山如画,转载请注明出处:http://www.125jz.com/2819.html

(0)
江山如画的头像江山如画管理团队
上一篇 2018年10月24日 上午9:02
下一篇 2018年10月24日 上午11:08

99%的人还看了以下文章

  • 网络编程 ASP.NET(C#)学习笔记二:数据类型-值类型

    C#中数据类型主要分为两大类:值类型和引用类型。本节课主要讲解值类型的分类和结构类型、枚举类型的定义和使用。 值类型: C#中值类型包括3种:简单类型、结构类型和枚举类型。 简单类型包括整数类型、字符类型、实数类型和布尔类型等,在此不做介绍,随便找本书看下即可。 结构类型:用于定义复杂的数据类型。如图书信息(包括书名,作者,出版社,价格等等),坐标点的信息(…

    2018年1月30日
    1.4K0
  • idea不识别@webServlet注解,javax.servlet.htttp 找不到的解决方法

    在servlet3.0以后,web.xml中对Servlet配置,可以通过@WebServlet注解配置.下面是@WebServlet的属性列表: 属性名 类型 描述 name String 指定Servlet 的 name 属性,等价于 <servlet-name>。如果没有显式指定,则该 Servlet 的取值即为类的全限定名。 value …

    2020年8月22日 编程开发
    15.7K0
  • 一文让你快速理解欠拟合和过拟合,以及解决欠拟合和过拟合的方法?(精)

    前面分享过《深度学习中的激活函数、防止过拟合的方法》、《最清楚的过拟合(Overfitting)、欠拟合讲解》,今天给125建站网再给大家梳理一下,让你快速理解欠拟合和过拟合,以及解决欠拟合和过拟合的方法? 欠拟合与过拟合 欠拟合是指模型在训练集、验证集和测试集上均表现不佳的情况; 过拟合是指模型在训练集上表现很好,到了验证和测试阶段就大不如意了,即模型的泛…

    2023年1月16日
    4430
  • python 循环语句的应用:水仙花数判断及爱因斯坦阶梯编程

    一、水仙花数判断程序 1.任务内容: 水仙花数是一个三位整数,如153是一个水仙花数,是因为该数的百位的立方、十位的立方、个位的立方和等于该数本身,如下所示: 2.程序编写要求: 使用for语句完成; 统计水仙花数个数的值保存到变量中,要求自动进行统计 •输出结果如下所示: 153 是水仙数370 是水仙数371 是水仙数407 是水仙数三位数中有4个水仙数…

    2022年5月11日
    1.1K1
  • HTTP错误 403.14 服务器配置为不列出此目录内容

    开发一个企业网站,使用ASP技术,在本地通过IIS管理器调试,出现 如下问题: HTTP 错误 403.14 – Forbidden Web 服务器被配置为不列出此目录的内容 解决方法: 在”功能视图“,中找到”目录浏览“,双击进入 在目录浏览右侧操作中选择”启用“! 这时再浏览网站,可以看到已经不报错了,但是网站是以文件目录的形式展现的! 这是…

    2018年7月3日 编程开发
    2.8K0
  • 详解如何在myeclipse中运行JSP,Run As none applicable(图)

    在MyEclipse中打开JAVA Project时想运行单个JAVA文件,如Hello.java文件,可以在Hello.java右键Run As 后面出现java Application,点击即可运行。 在myEclipse中打开web project,想运行单个JSP文件或项目,在jsp文件上右键Run As 没有”run on server…

    2020年2月23日
    8.3K0

发表回复

登录后才能评论