String、StringBuffer和StringBuilder的理解

  这三个类学过已经有一段时间了,想通过这篇文章再将其复习一下,以求温故知新。

  首先说一下三者各自的特性

  • String:
  1. String是不可变类。为什么说是不可变呢,进入String的源码即可知道,String底层维护的是一个数组,而这个数组是用private final修饰的。private说明它是不对外暴露的,final是不可以更改的。
  2. String的不可变性导致一旦一个String对象被创建后,包含在这个对象中的字符序列是不可以改变的,直至这个对象的销毁。在这里或许有人会提出这样的问题:String s="abc";   s=s+"def";  这不是字符串明明被改变了嘛,为什么说不可变呢?原因就是:这是两个对象,每次对String类的字符串进行更改就等同于创建了一个新的对象。所以如果会对字符串对象进行频繁的更改,不建议使用String类。
  3. 创建String对象的两种方法:① String s ="";② String s =new String();
  4. 再说一种情况:String s1=“hello”;String s2=“world”;String s3=s1+s2;很明显最后s3输出为helloworld。而这是为什么呢?有些人会说是JVM直接在s1后面将s2加上的。但这就违反了String类的不可变性。其实是JVM首先开辟出了一块新的内存区域,然后再将s1和s2复制到这块区域中。这样很明显造成了内存空间的浪费和效率的降低,于是便引出下面将要说明的StringBuilder和StringBuffer。
  5. 这里再说一个小知识点:

String str1="hello";

String str2="hello";

String str3=new String("hello");

String str4=new String("hello");

①System.out.println("str1==str2?"+(str1==str2));  //true

②System.out.println("str2==str3?"+(str2==str3));  //false

③System.out.println("str3==str4?"+(str3==str4));   //false

④System.out.println("str3.equals(str4)?"+(str3.equals(str4)));//true

String str1="hello"; 这种方式创建字符串的时候,JVM首先会检查字符串常量池中是否存在该字符串的对象,如果已经存在,那么就不会在字符串常量池中再创建了,直接返回该字符串再字符串常量池中的内存地址,如果该字符串对象还不存在在字符串常量池中,那么就会在字符串常量池中先创建该字符串的对象,然后再返回。

String str3=new String("hello");这种方式创建字符串对象的时候,首先JVM先会检查字符串常量池中是否存在“hello”的字符串,如果已经存在,则不会在字符串常量池中创建了,如果还未存在,那么就在字符串常量池中创建“hello”字符串对象,然后还会到堆内存中再创建一份字符串对象,把字符串常量池中的“hello”字符串内容拷贝到堆内存中的字符串对象,然后返回堆内存中的字符串对象的内存地址。

代码①:结果为true,因为创建str2时字符串常量池中已经存在“hello”了,所以就不会再创建了,直接将str1的地址赋给str2。

剩下的②、③、④代码就不作解释了,请自行思考。需要说明的一点就是String类重写了equals()方法。

  • StringBuffer:
    • 在进行介绍之前先介绍一下Buffer。
      • Buffer的意思为缓冲区。就是在内存中有一小块区域,要放什么内容,首先要放在这一小块区域中,然后再准备往其他地方放。就比如说有一个水流很小的水龙头,我们去接水都是用桶等容器去接,接满后再将桶中的水倒入其他地方。而这个桶就相当于一个缓冲区。

下面开始StringBuffer的正文:

  1. StringBuffer代表的是一个字符序列可变的字符串。当一个StringBuffer对象被创建以后,通过StringBuffer提供的append()、insert()、reverse()等方法,就可以改变这个字符串对象的字符序列。
  2. StringBuffer底层维护的是一个字符数组。如果使用无参构造方法,这个字符数组的默认初始容量为16。 如果长度不够用,就自动增长为原来的两倍加2。
  3. 一旦通过StringBuffer生成了最终想要的字符串,就可以调用它的toString()方法将其转换为一个String对象。
  4. StringBuffer是线程安全的,操作效率低。所谓线程安全是指在一个时间段内只允许一个线程来操作这份代码。
  • StringBuilder:
  1. StringBuilder类也代表了字符串对象,和StringBuffer基本相似。
  2. StringBuilder是线程非安全的,操作效率高。所谓线程不安全指在一个时间段内一个代码可以由多个线程同时来执行。
  • 总结:如果对字符串操作的少就用String,否则每次操作字符串都会产生一个新的对象,内存会吃不消的。如果单线程就用StringBuilder,因为StringBuilder是并没有实现线程安全,但是操作效率高。如果是多线程就使用StringBuffer,因为StringBuffer是线程安全的。

以上内容为自己整理的所学到的知识,当然还有很多不足,这需要您的指出。其中还有很多知识点没有列出,毕竟知识点太多了,越学习就越发现知识的海洋的广阔以及自己的渺小与无知,自己需要学的东西还非常多。路漫漫其修远兮,吾将上下而求索。

Java之String、StringBuffer、StringBuilder的更多相关文章

  1. java中 String StringBuffer StringBuilder的区别

    * String类是不可变类,只要对String进行修改,都会导致新的对象生成. * StringBuffer和StringBuilder都是可变类,任何对字符串的改变都不会产生新的对象. 在实际使用 ...

  2. java中String,StringBuffer,StringBuilder之间的区别

    文章转载自:http://www.cnblogs.com/frankliiu-java/archive/2010/07/05/1771537.html String是固定长度的字符串,如果要发生变化必 ...

  3. java 比较String StringBuffer StringBuilder

    String 字符串常量StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非线程安全) 简要的说, String 类型和 StringBuffer 类型的主要性能 ...

  4. Java学习|String,StringBuffer,StringBuilder?

    1 String   (1) String的创建机理 由于String在Java世界中使用过于频繁,Java为了避免在一个系统中产生大量的String对象,引入了字符串常量池.其运行机制是:创建一个字 ...

  5. Java中String/StringBuffer/StringBuilder区别(转)

    1.三者在执行速度方面的比较:StringBuilder >  StringBuffer  >  String 2.String <(StringBuffer,StringBuild ...

  6. Java之String,StringBuffer,StringBuilder类

    在 java 语言中, 用来处理字符串的的类常用的有 3 个: String.StringBuffer.StringBuilder. 它们的异同点: 1) 都是 final 类, 都不允许被继承; 2 ...

  7. Java的String&StringBuffer&StringBuilder

    一:String类 1.String对象的初始化 由于String对象特别用,所以在对String对象进行初始化时,Java提供了一种简化的特殊语法,格式如下: String s = "ab ...

  8. java中string , StringBuffer , StringBuilder 区别

    1.String String变量的值不能改变,如果要改变String变量的值,虚拟机首先会遍历方法区中的字符串常量,如果存在需要的值,则虚拟机直接把此常量值的地址分配给String变量,如果不存在这 ...

  9. 探秘Java中String、StringBuilder以及StringBuffer

    探秘Java中String.StringBuilder以及StringBuffer 相信String这个类是Java中使用得最频繁的类之一,并且又是各大公司面试喜欢问 到的地方,今天就来和大家一起学习 ...

  10. Java学习笔记--String StringBuffer StringBuilder

    String StringBuffer StringBuilder String http://docs.oracle.com/javase/7/docs/api/ 中文: http://www.cn ...

随机推荐

  1. 分享 C++图像处理的代码简易示例

    采用Decoder:stb_image https://github.com/nothings/stb/blob/master/stb_image.h 采用Encoder:tiny_jpeghttps ...

  2. JS 无法清除Cookie的解决方法

    JS 无法清除Cookie的解决方法   项目中使用sdmenu.js时,需要在登录时清除Cookie,而sdmenu默认是会保存Cookie的 下面是sdmenu.js保存Cookie的方法 doc ...

  3. java集合框架的讲解

    下面要开始java中相关集合框架的学习啦. Are you ready?Let's go~~ 今天要讲解的Java中的集合框架. 1) 首先查看jdk中Collection类的源码后会发现如下内容: ...

  4. linux下U盘挂载

    linux下挂载U盘 一.Linux挂载U盘:1.插入u盘到计算机,如果目前只插入了一个u盘而且你的硬盘不是scsi的硬盘接口的话,那它的硬件名称为:sda1,可以用"fdisk -l&qu ...

  5. Exception in thread "main" java.lang.ClassNotFoundException: com.mysql.jdbc.Driver

    这个问题当然是找不到mysql的驱动类,可能是环境CLASSPATH有问题或者就是那个人没有加载jdbc的驱动.我在网上下载mysql-connector-java-5.0.8-bin.jar一个这个 ...

  6. 嵌入式GPIO接口及操作(一)

    GPIO意思就是通用输入输出,一些引脚可以通过他们输出高低电平,或者通过它们读入引脚的状态.对GPIO的操作是对所有硬件的操作最基本的技能.一.通过寄存器来操作GPIO引脚,一个引脚可以用于输入.输出 ...

  7. box-sizing 属性应用

    1.box-sizing属性功能 官方说明文档为:http://www.w3school.com.cn/cssref/pr_box-sizing.asp box-sizing 属性允许您以特定的方式定 ...

  8. Spring (三)

    1.1 Spring的事务管理 1.1.1事务 事务:指的是逻辑上一组操作,要么全部成功,要么全部失败. 事务特性: 原子性:事务不可分割. 一致性:事务执行前后,数据完整性保存一致. 隔离性:一个事 ...

  9. CSS选择器 - 性能的探究及提升

    [本博客为原创:http://www.cnblogs.com/HeavenBin/]  前言: 在工作中编写CSS样式表时随着选择器层数的增加总会看到选择器又丑又长的情况,利用工作之余研究从其命名再到 ...

  10. MFC对话框中显示背景图片

    在MFC对话框中显示图片,四个步骤. 1.首先得在VC6.0或者VS2008(其他版本也是一样)中导入GDI文件.(网上下载:) GDI含义是图形设备接口,主要任务是负责系统与绘图程序之间的信息交换, ...