String,StringBuffer,StringBuilder的区别

     在Java开发中String绝对是我们最常用的一种引用类型,它可不是八大基础数据类型(byte、short、int、long,float、double,char,boolean)之一,但它的实际应用不亚于这些基础数据类型,所以我们有必要来学学它,今天我们就来学习一下String,StringBuffer,StringBuilder的区别:

     String 就是一个定义字符串常用的标识符,基本我们对字符串没有特殊要求的话,都会用它来定义,他的主要特点是:它是字符串常量,用final定义的,所以它的长度是不可变的,它定义后就一直是那个值,不会再被改变;String类是final类,也即意味着String类不能被继承,并且它的成员方法都默认为final方法。在Java中,被final修饰的类是不允许被继承的。String类其实是通过char数组来保存字符串的,无论是sub、split、concat还是replace操作都不是在原有的字符串上进行的,而是重新生成了一个新的字符串对象。也就是说进行这些操作后,最原始的字符串并没有被改变。所以永远记住一点:“对String对象的任何改变都不影响到原对象,相关的任何change操作都会生成新的对象”

    StringBuffer:字符串变量(Synchronized,即线程安全)。如果要频繁对字符串内容进行修改,出于效率考虑最好使用 StringBuffer,如果想转成 String 类型,可以调用 StringBuffer 的 toString() 方法。StringBuffer是线程安全的可变字符序列。在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容,也可将字符串缓冲区安全地用于多个线程。

    StringBuilder:字符串变量(非线程安全)。在内部,StringBuilder 对象被当作是一个包含字符序列的变长数组。 是一个可变的字符序列,是 JDK5.0 新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍),StringBuilder和StringBuffer类拥有的成员属性以及成员方法基本相同,区别是StringBuffer类的成员方法前面多了一个关键字:synchronized,不用多说,这个关键字是在多线程访问时起到安全保护作用的,也就是说StringBuffer是线程安全的,但StringBuilder执行效率较高。

 

     String、StringBuilder、StringBuffer三者的执行效率:StringBuilder > StringBuffer > String

     这三个类是各有利弊,应当根据不同的情况来进行选择使用:

  当字符串相加操作或者改动较少的情况下,建议使用 String str="hello"这种形式;

  当字符串相加操作较多的情况下,建议使用StringBuilder,

     如果采用了多线程,为了保证安全性,则使用StringBuffer。

 

  下面是一些常见的一些面试笔试题,若有不正之处,请谅解和批评指正。

       1. 下面这段代码的输出结果是什么?

  String a = "hello2";   String b = "hello" + 2;   System.out.println((a == b));

  输出结果为:true。原因很简单,"hello"+2在编译期间就已经被优化成"hello2",因此在运行期间,变量a和变量b指向的是同一个对象。

      2.下面这段代码的输出结果是什么?

  String a = "hello2";    String b = "hello";       String c = b + 2;       System.out.println((a == c));

  输出结果为:false。由于有符号引用的存在,所以  String c = b + 2;不会在编译期间被优化,不会把b+2当做字面常量来处理的,因此这种方式生成的对象事实上是保存在堆上的。         因此a和c指向的并不是同一个对象。

     3.下面这段代码的输出结果是什么?

 

     对上面结果的解释说明:
    首先上面的比较过程是直接拿 == 来比较的,没有用equal方法,那么用 == 来比较的话,比较的是地址。并不是值。
    可以看到,a,b,d,三个字符串直接用 == 比较,比较出来的结果都是true。是相等的。
    意思就是说这三个变量在空间上都是指向同一个内存地址。这就涉及到一个字符串常量池的问题啦。
    但是和c比较的时候,却不相等,因为,c是new出来的,记得当时学习的时候,new都是在堆内存里面的,新开辟的空间。
    所以,地址肯定就不相同啦!

 

posted @ 2022-03-20 19:25  柯南新一  阅读(36)  评论(0)    收藏  举报