美文网首页
Java中String、StringBuffer、StringB

Java中String、StringBuffer、StringB

作者: taoguan | 来源:发表于2019-10-19 21:21 被阅读0次

    前言

    Java中用于处理字符串常用的有三个类:java.lang.String、java.lang.StringBuffer、java.lang.StrungBuilder。三者共同之处:都是final类,不允许被继承,主要是从性能和安全性上考虑的,因为这几个类都是经常被使用着,且考虑到防止其中的参数被修改影响到其他的应用。

    String类

    先看一下JDK中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
    
        public String() {
            this.value = "".value;
        }
    
        public String(String original) {
            this.value = original.value;
            this.hash = original.hash;
        }
    
        public String(char value[]) {
            this.value = Arrays.copyOf(value, value.length);
        }
    
    ...
    

    可以看到String类和value都是final类型的,这样就表明String是无法被继承的,value是无法被改写的。当通过String的构造函数初始化新的String对象时,也只是根据传入的引用对象的value和hashcode进行了赋值。

    StringBuilder和StringBuffer

    先看一下它们在JDK中的部分源码:

    abstract class AbstractStringBuilder implements Appendable, CharSequence {
        /**
         * The value is used for character storage.
         */
        char[] value;
    
        /**
         * The count is the number of characters used.
         */
        int count;
    
       
        AbstractStringBuilder() {
        }
        AbstractStringBuilder(int capacity) {
            value = new char[capacity];
        }
    ...
    }
    
    public final class StringBuilder
        extends AbstractStringBuilder
        implements java.io.Serializable, CharSequence
    {
        public StringBuilder() {
            super(16);
        }
    
        public StringBuilder(int capacity) {
            super(capacity);
        }
    
        public StringBuilder(String str) {
            super(str.length() + 16);
            append(str);
        }
    
        @Override
        public StringBuilder append(String str) {
            super.append(str);
            return this;
        }
    ...
    }
    
    public final class StringBuffer
        extends AbstractStringBuilder
        implements java.io.Serializable, CharSequence
    {
    
        private transient char[] toStringCache;
    
        public StringBuffer() {
            super(16);
        }
    
        public StringBuffer(int capacity) {
            super(capacity);
        }
    
        public StringBuffer(String str) {
            super(str.length() + 16);
            append(str);
        }
    
        @Override
        public synchronized StringBuffer append(String str) {
            toStringCache = null;
            super.append(str);
            return this;
        }
    ...
    }
    

    可以看到StringBuffer和StringBuilder一样,都是用了char数组保存value,append也是调用了AbstractStringBuilder的append方法。区别在于StringBuffer中的方法上加了synchronized关键字。

    三者的区别

    1、执行速度

    StringBuilder > StringBuffer > String

    我们知道String是字符串常量,不可变对象,因此每次对String进行操作的时候实际上是生成了一个新的String对象,然后将指针指向新的String对象上,之前的String对象就没有了指针引用,当内存中无引用的对象多了之后,就会触发JVM的GC操作了。

    StringBuilder和StringBuffer是字符串变量,因此当我们对字符串做操作的时候,实际上都是操作的同一个对象,不会创建新的对象。

    注意:

    String str="hel"+"lo";
    
    String a = "hel";
    String b ="lo";
    String c = a+b;
    

    上面的两部分代码虽然输出的结果都是“hello”,但是在jvm中的内存分布是完全不同的。

    String str="hel"+"lo"; 中的str是一个编译时常量,最后分配到内存里面的只有"hello" 这一款内存区域。
    而下面的三行代码,则需要在内存中分配三块地址,【"hel","lo","hello"】。

    2、线程安全

    StringBuilder是线程不安全的,而StringBuffer是线程安全的。

    java.lang.StringBuilder一个可变的字符序列是5.0新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。

    结语

    String:适用于少量的字符串操作的情况
    StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
    StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

    相关文章

      网友评论

          本文标题:Java中String、StringBuffer、StringB

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