浅谈Java中String、StringBuilder、StringBuffer的联系与区别

浅谈Java中String、StringBuilder、StringBuffer的联系与区别

String是Java 开发工作者使用得最频繁的类之一,了解并学习String、StringBuilder、StringBuffer这几个类,分析它们的异同点以及了解各个类适用的场景,相信都有利于日常编码与求职面试。

本文目录大纲
一.你了解String类吗?
二.String、StringBuffer、StringBuilder的联系
三.深入理解String、StringBuffer、StringBuilder

一.你了解String类吗?

想了解一个类,最好的办法就是查看一个类的源代码

  public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

    /** Cache the hash code for the string */
    private int hash; // Default to 0

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = -6849794470754667710L;

    /**
     * Class String is special cased within the Serialization Stream Protocol.
     */
    private static final ObjectStreamField[] serialPersistentFields =
        new ObjectStreamField[0];
    ......

    public String substring(int beginIndex, int endIndex) {
        if (beginIndex < 0) {
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        if (endIndex > value.length) {
            throw new StringIndexOutOfBoundsException(endIndex);
        }
        int subLen = endIndex - beginIndex;
        if (subLen < 0) {
            throw new StringIndexOutOfBoundsException(subLen);
        }
        return ((beginIndex == 0) && (endIndex == value.length)) ? this
                : new String(value, beginIndex, subLen);
    }
    public String concat(String str) {
        int otherLen = str.length();
        if (otherLen == 0) {
            return this;
        }
        int len = value.length;
        char buf[] = Arrays.copyOf(value, len + otherLen);
        str.getChars(buf, len);
        return new String(buf, true);
    }
    ......
}

通过以上代码可以看出:

  1. String类是final类,意味着String类不能被继承,并且它的成员方法都默认为final方法
  2. String类是通过char数组保存字符串的
  3. 由成员方法可看出,对字符串的操作都不是在原有的字符串上进行的,而是重新生成了一个新的字符串对象,也就是说: “对String对象的任何改变都不影响到原对象,相关的任何操作都会生成新的对象”

二.String、StringBuffer、StringBuilder的联系

查看相关API可以发现,String、StringBuffer、StringBuilder都实现了CharSequence接口,内部使用char数组保存字符

  1. String:字符串常量,是不可改变的量,即创建后就不能在修改了
  2. StringBuffer:字符串变量(线程安全),是可变字符串序列
  3. StringBuilder:字符串变量(线程不安全),是可变字符串序列

因为String是不可改变的对象,因此在每次对String类型进行改变的时候其实都等同于生成了一个新的String对象,任何将指针指向新的String对象,所以在经常改变内容的字符串最好不要用String,因为每次生成对象都会对系统性能产生影响,当内存中无引用对象多了以后,JVM的GC会进行工作,影响系统效率。

因此,在字符串不经常变化的场景中可以使用String类,例如常量的声明,少量的变量运算;在频繁进行字符串运算(如拼接、替换、删除等),并且运行在多线程环境中,则可以考虑使用StringBuffer,若是单线程的环境,则可以考虑使用StringBuilder。

三.深入理解String、StringBuffer、StringBuilder

  1. String str = “hello world” 和 String str = new String(“hello world”)的区别
    观察下列代码
public class Main() {
    public static void main(String[] args) {
        String str1 = "hello world";
        String str2 = new String("hello world");
        String str3 = "hello world";
        String str4 = new String("hello world");

        System.out.println(str1==str2);
        System.out.println(str1==str3);
        System.out.println(str2==str4);
    }
}

输出结果:
false
true
false

之所以会出现这样的结果,这是因为JVM 的内存机制中,在class文件中有一部分存储编译期间生成的字面常量以及符号引用,在编译运行期间对应着方法区的运行时常量池。
因此在上述代码中,String str1="hello world"和String str3="hello world"都在编译期间生成了字面常量和符号引用,运行期间字面常量"hello world"被存储在运行时常量池;通过这种方式将String跟引用绑定的话,JVM执行引擎会先在运行时常量池查找是否存在系统的字面常量;否则在运行时常量池开辟一个空间来存储该字面常量,并将引用指向该字面常量。
总所周知,通过new关键字来生成对象是在堆区进行的,而在堆区进行对象生成的过程是不会去检测该对象是否已经存在的。因此通过new来创建对象,创建出的一定是不同的对象,即使字符串的内容是相同的。

  1. 关于equal和==的区别
    观察下列代码
public class Main() {
    public static void main(String[] args) {
        String str1 = "hello world";
        String str2 = new String("hello world");
        String str3 = "hello world";
        String str4 = new String("hello world");

        System.out.println(str1.equals(str2));
        System.out.println(str1.equals(str3));
        System.out.println(str2.equals(str4));
    }
}

输出结果:
true
true
true

之所以会出现这样的结果,是因为用于比较两个对象的时候,用来检测是否两个引用指向了同一块内存
equals()是Object的方法,默认情况下,它与
一样,比较地址;然而String类重写了这个方法,它的equals()通过比较对象的value值,判断两个对象是否相等

  1. String、StringBuilder、StringBuffer三者的执行效率
    一般情况下String、StringBuilder、StringBuffer三者的执行效率:StringBuilder>StringBuffer>String

参考文档:http://www.cnblogs.com/dolphin0520/p/3778589.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值