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. Js 获取时间戳

    //获取时间戳 单位:秒: //1. 获取当前时间戳 function getUnixTime(){ var date = new Date(); //使用getTime方法: var unix_ti ...

  2. iOS底层学习-KVC使用实践以及实现原理

    简介 KVC(Key-value coding)键值编码,顾名思义.额,简单来说,是可以通过对象属性名称(Key)直接给属性值(value)编码(coding)"编码"可以理解为& ...

  3. 初学Python之 安装包的抉择~~

    上面的都是windows系统平台的安装包,哇,有没有后宫三千,不知道"临幸"哪一个的感觉~.~ 看了下面的你就明白啦. 毫无疑问,x86适合32位操作系统:x86-64适合64位操 ...

  4. swift3.0 对UITextField()输入框输入的内容进行监控

    首先需要继承 UITextFieldDelegate class TestViewController: UIViewController,UITextFieldDelegate{ } 添加事件委托 ...

  5. PyCharm中光标变粗的解决方法

    pycharm中光标变粗,如下: 原因:光标进入了改写状态. 解决方法:按一下键盘中的Insert键就好了.

  6. 安徽省2016“京胜杯”程序设计大赛_K_纸上谈兵

    纸上谈兵 Time Limit: 1000 MS Memory Limit: 65536 KB Total Submissions: 3 Accepted: 1 Description     战国时 ...

  7. Spring思维导图(一)

    关于Spring Spring是一个开源框架,是为了解决企业应用程序开发复杂性而创建的.框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架 ...

  8. iconfont 使用

    阿里巴巴适量图库  http://www.iconfont.cn/ 官方帮助中有非常详细的操作指导 http://www.iconfont.cn/help/detail?spm=a313x.77810 ...

  9. 关于Java中面向对象章节、IO 流中的重点基础知识。

    一.面向对象的三大特征,以及作用. 答:面向对象的三大特征即,封装性.继承性.多态性. 其分别的作用为 : 封装作用:将数据封装起来,提高数据的安全性, 继承作用:提高代码的复用性,减少冗余代码. 多 ...

  10. 自定义类似于Jquery UI Selectable 的Vue指令v-selectable

    话不多说,先看效果. 其实就是一个可以按住鼠标进行一个区域内条目选择的功能,相信用过Jquery UI 的都知道这是selectable的功能,然而我们如果用Vue开发的话没有类似的插件,当然你仍然可 ...