美文网首页
Java中的String、StringBuilder和Strin

Java中的String、StringBuilder和Strin

作者: 丶眼前人 | 来源:发表于2019-03-07 17:12 被阅读0次

    String 是 Java 语言非常基础和重要的类,它是典型的 Immutable 类,被声明成为 final class,所有属性也都是 final 的。也由于它的不可变性,类似拼接、裁剪字符串等动作,都会产生新的 String对象。

    StringBuffer 是为解决上面提到拼接产生太多中间对象的问题而提供的一个类,我们可以用 append 或者add 方法,把字符串添加到已有序列的末尾或者指定位置。StringBuffer 本质是一个线程安全的可修改字符序列,它保证了线程安全,也随之带来了额外的性能开销,所以除非有线程安全的需要,不然还是推荐使用它的后继者,也就是 StringBuilder

    StringBuilder 是 Java 1.5 中新增的,在能力上和 StringBuffer 没有本质区别,但是它去掉了线程安全的部分(去掉关键字synchronized),有效减小了开销,是绝大部分情况下进行字符串拼接的首选。

    异同点对比(Java 1.8):
    String类中使用字符数组保存字符串,因为有“final”修饰符,所以可以知道string对象是不可变的
    private final char value[];

    StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,这两种对象都是可变的
    char[] value;

    在我们创建StringBuilder和StringBuffer时,对应字符数组大小是有默认值的,构建时初始字符串长度加 16,如果初始没有传入字符串,初始值即为16
    public StringBuffer() { super(16);}

    执行速度:StringBuilder (非线程安全)> StringBuffer > String
    String:适用于少量的字符串操作的情况
    StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
    StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

    String#intern()扩展
    String 在 Java 6 以后提供了 intern()方法,目的是提示 JVM 把相应字符串缓存起来,以备重复使用。在我们创建字符串对象并调用 intern() 方法的时候,如果已经有缓存的字符串,就会返回缓存里的实例,否则将其缓存起来。一般来说,JVM 会将所有的类似“abc”这样的文本字符串,或者字符串常量之类缓存起来。
    intern()方法在不同的JDK版本,有着较大的变化,这里不细讲,参考网上其他文章,了解即可intern深入分析
    以下代码在JDK1.8环境执行结果

            String a = new String("aa");
            a.intern();
            String b = "aa";
            System.out.println(a == b); // false
    
            String c = new String("1");
            c = c.intern();
            String d = "1";
            System.out.println(c == d); // true
    
            String s3 = new String("1") + new String("1");    // 此时生成了四个对象 常量池中的"1" + 2个堆中的"1" + s3指向的堆中的对象(注此时常量池不会生成"11")
            s3.intern();    // jdk1.7之后,常量池不仅仅可以存储对象,还可以存储对象的引用,会直接将s3的地址存储在常量池
            String s4 = "11";    // jdk1.7之后,常量池中的地址其实就是s3的地址
            System.out.println(s3 == s4); // true
    
            s3 = new String("2") + new String("2");
            s4 = "22";        // 常量池中不存在22,所以会新开辟一个存储22对象的常量池地址
            s3.intern();    // 常量池22的地址和s3的地址不同
            System.out.println(s3 == s4); // false
    

    相关文章

      网友评论

          本文标题:Java中的String、StringBuilder和Strin

          本文链接:https://www.haomeiwen.com/subject/fnvcpqtx.html