String,StringBuilder, StringBuffer有什么区别

String,StringBuilder, StringBuffer有什么区别我们可以看到,String 是使用final修饰的,说明这个类不可以被继承,同时,value也是用final修饰的,说明value也重新指向新的

大家好,欢迎来到IT知识分享网。

String

我们来看一下String的定义

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    
    private final char value[];
}

我们可以看到,String 是使用final修饰的,说明这个类不可以被继承,同时,value也是用final修饰的,说明value也重新指向新的应用,因此,String类是不可变的,但是对于这样一个问题,我们经常会感到困惑,我们来看一下这个代码

public class Test {

    public static void main(String[] args){
        
        String name = "Tom";
        
        name = "Jack";

    }
}

很多人会有一个疑问,不是说String是一个不可变的类么,那么为什么name的值改变了,这么理解是错误的,实际上,在内存中有一个Tom的字符串,然后,name只是指向了这个字符串,然后通過name = “Jack”;只是name指向了一个新的字符串,而在内存中,还是有一个Tom的字符串,这个是没有变化的,因此字符串是没有发生变化的。

StringBuilder

StringBuilder是一个可变的字符串,我们经常会使用StringBuilder来做字符串的拼接工作。在很多地方,我们都能看到这样一种说法,在for循环中,推荐我们使用StringBuilder来拼接字符串,而不是使用+,我们来看一下这段代码,看看究竟是什么原因?

public class StringBuilderTest {

    public static void main(String[] args) {
        List<String> list = Lists.newArrayList("str1", "str2", "str3", "str4");
        String value = "";
        for (String str : list) {
            value = value + str;
        }
        System.out.println(value);
    }
}

我们来使用javap -v来看一下+底层的实现原理

public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=4, locals=5, args_size=1
         0: iconst_4
         1: anewarray     #2                  // class java/lang/String
         4: dup
         5: iconst_0
         6: ldc           #3                  // String str1
         8: aastore
         9: dup
        10: iconst_1
        11: ldc           #4                  // String str2
        13: aastore
        14: dup
        15: iconst_2
        16: ldc           #5                  // String str3
        18: aastore
        19: dup
        20: iconst_3
        21: ldc           #6                  // String str4
        23: aastore
        24: invokestatic  #7                  // Method com/google/common/collect/Lists.newArrayList:([Ljava/lang/Object;)Ljava/util/ArrayList;
        27: astore_1
        28: ldc           #8                  // String
        30: astore_2
        31: aload_1
        32: invokeinterface #9,  1            // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
        37: astore_3
        38: aload_3
        39: invokeinterface #10,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
        44: ifeq          81
        47: aload_3
        48: invokeinterface #11,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
        53: checkcast     #2                  // class java/lang/String
        56: astore        4
        58: new           #12                 // class java/lang/StringBuilder
        61: dup
        62: invokespecial #13                 // Method java/lang/StringBuilder."<init>":()V
        65: aload_2
        66: invokevirtual #14                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        69: aload         4
        71: invokevirtual #14                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        74: invokevirtual #15                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        77: astore_2
        78: goto          38
        81: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
        84: aload_2
        85: invokevirtual #17                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        88: return

我们来看一下58行到74行,这一段代码就是用来实现+号的,它底层采用就是StringBuilder相当于这段代码

public class StringBuilderTest {

    public static void main(String[] args) {
        List<String> list = Lists.newArrayList("str1", "str2", "str3", "str4");
        String value = "";
        for (String str : list) {
            value = new StringBuilder().append(value).append(str).toString();
        }
        System.out.println(value);
    }
}

通过这段代码,我们只带,+每次都会创建一个StringBuilder对象,英雌,如果我们显示通过StringBuilder显示拼接字符串,这样会减少很多对象的创建,因此可以提升程序的性能,最终,可能改造成这段代码

public class StringBuilderTest {

    public static void main(String[] args) {
        List<String> list = Lists.newArrayList("str1", "str2", "str3", "str4");
        StringBuilder sb = new StringBuilder();
        for (String str : list) {
            sb.append(str);
        }
        System.out.println(sb.toString());
    }
}

StringBuffer

StringBuffer也是一个可变的字符串拼接类,通过它同样可以拼接字符串,那么它和StringBuilder究竟有什么区别呢,我们来看一下源码

String,StringBuilder, StringBuffer有什么区别

StringBuffer的方法都加了synchronized锁,因此StringBuffer是一个线程安全的类,因此,我们在多线程的环境了,使用StringBuffer,在单线程的环境下StringBuilder,这样才是最优的使用原则

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/58921.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信