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. 确认oracle数据库错误日志文件位置

     在命令行里面输入: show parameter background_dump_dest 执行之后会显示一个目录,这个目录就是错误日志目录 在这目录下回有alert*.log 类似这样的文件,这个 ...

  2. [补档]暑假集训D1总结

    归来 今天就这样回来了,虽然心里极其不想回来(暑假!@#的只有一天啊喂),但还是回来了,没办法,虽然不喜欢这个地方,但是机房却也是少数能给我安慰的地方,心再累,也没有办法了,不如好好集训= = %da ...

  3. 关于Python3中venv虚拟环境

    Python3.3以上的版本通过venv模块原生支持虚拟环境,可以代替Python之前的virtualenv. 该venv模块提供了创建轻量级"虚拟环境",提供与系统Python的 ...

  4. CentOS上javaweb开发环境搭建

    CentOS上javaweb开发环境搭建 安装jdk yum list java* yum install java-1.7.0-openjdk* -y java -version 安装tomcat ...

  5. 关于发布中报“未能加载文件或程序集“Newtonsoft.Json”或它的某一个依赖项”的问题解决方法

    遇到这个问题了,我也是醉了,开发就一个还在忙别的事情,我想想自己解决 你们遇到过吗?我在网上找到好多解决的方法,比如改webconfig文件,或者改package.config文件,都没用.但是我看到 ...

  6. Android -- 自定义view实现keep欢迎页倒计时效果

    1,最近打开keep的app的时候,发现它的欢迎页面的倒计时效果还不错,所以打算自己来写写,然后就有了这篇文章. 2,还是老规矩,先看一下我们今天实现的效果 相较于我们常见的倒计时,这次实现的效果是多 ...

  7. 关于"软件评测师"

    参考书目 <软件评测师考试考点分析与真题详解>http://item.taobao.com/item.htm?spm=a1z09.2.9.82.qx67QK&id=18924026 ...

  8. Vue过渡效果之CSS过渡

    前面的话 Vue 在插入.更新或者移除 DOM 时,提供多种不同方式的应用过渡效果.本文将从CSS过渡transition.CSS动画animation及配合使用第三方CSS动画库(如animate. ...

  9. C#高级编程:泛型优点和特性

    泛型是CLR 2.0的一个新特性,在CLR 1.0中,要创建一个灵活的类或方法,但该类或方法在编译期间不知道使用什么类,就得以Object类为基础.而Object在编译期间没有类型安全性,因此必须进行 ...

  10. JavaScript模块化 --- Commonjs、AMD、CMD、es6 modules

    随着前端js代码复杂度的提高,JavaScript模块化这个概念便被提出来,前端社区也不断地实现前端模块化,直到es6对其进行了规范,下面就介绍JavaScript模块化. 这篇文章还是希望能给大家一 ...