String、StringBuilder、StringBuffer之间的区别
发布日期:2021-05-07 21:34:18 浏览次数:32 分类:精选文章

本文共 9678 字,大约阅读时间需要 32 分钟。

String中的++符号操作的原理

/** * @author lizhangyu * @date 2020/6/13 1:30 */public class StringOperator {       public static void main(String[] args) {           StringBuffer sbf = new StringBuffer();        String a = "a";        String b = "b";        String c = "23";        String d = "2";        String e = d + "3";        String ab = a+b;        StringBuilder sb = new StringBuilder();        sb.append(1);        System.out.println(c);        System.out.println(e);        System.out.println(c == e);    }}
  • 输出的结果为:
2323false
  • 字节码如下:
Compiled from "StringOperator.java"public class test1.StringOperator {     public test1.StringOperator();    Code:       0: aload_0       1: invokespecial #1                  // Method java/lang/Object."
":()V 4: return public static void main(java.lang.String[]); Code: 0: new #2 // class java/lang/StringBuffer 3: dup 4: invokespecial #3 // Method java/lang/StringBuffer."
":()V 7: astore_1 8: ldc #4 // String a 10: astore_2 11: ldc #5 // String b 13: astore_3 14: ldc #6 // String 23 16: astore 4 18: ldc #7 // String 2 20: astore 5 22: new #8 // class java/lang/StringBuilder 25: dup 26: invokespecial #9 // Method java/lang/StringBuilder."
":()V 29: aload 5 31: invokevirtual #10 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 34: ldc #11 // String 3 36: invokevirtual #10 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 39: invokevirtual #12 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 42: astore 6 44: new #8 // class java/lang/StringBuilder 47: dup 48: invokespecial #9 // Method java/lang/StringBuilder."
":()V 51: aload_2 52: invokevirtual #10 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 55: aload_3 56: invokevirtual #10 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 59: invokevirtual #12 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 62: astore 7 64: new #8 // class java/lang/StringBuilder 67: dup 68: invokespecial #9 // Method java/lang/StringBuilder."
":()V 71: astore 8 73: aload 8 75: iconst_1 76: invokevirtual #13 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 79: pop 80: getstatic #14 // Field java/lang/System.out:Ljava/io/PrintStream; 83: aload 4 85: invokevirtual #15 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 88: getstatic #14 // Field java/lang/System.out:Ljava/io/PrintStream; 91: aload 6 93: invokevirtual #15 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 96: getstatic #14 // Field java/lang/System.out:Ljava/io/PrintStream; 99: aload 4 101: aload 6 103: if_acmpne 110 106: iconst_1 107: goto 111 110: iconst_0 111: invokevirtual #16 // Method java/io/PrintStream.println:(Z)V 114: return}
  • 可以看到String++符号操作底层用的是StringBuilder类中的append方法,最后再通过toString()方法进行实现的。

StringBuilder中的append()方法

  • 可以看到方法中调用的是super中的append方法
@Override    public StringBuilder append(int i) {           super.append(i);        return this;    }
/**     * Appends the string representation of the {@code int}     * argument to this sequence.     * 

* The overall effect is exactly as if the argument were converted * to a string by the method {@link String#valueOf(int)}, * and the characters of that string were then * {@link #append(String) appended} to this character sequence. * * @param i an {@code int}. * @return a reference to this object. */ public AbstractStringBuilder append(int i) { if (i == Integer.MIN_VALUE) { append("-2147483648"); return this; } int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1 : Integer.stringSize(i); int spaceNeeded = count + appendedLength; ensureCapacityInternal(spaceNeeded); Integer.getChars(i, spaceNeeded, value); count = spaceNeeded; return this; }

  • 扩容机制:
/**     * For positive values of {@code minimumCapacity}, this method     * behaves like {@code ensureCapacity}, however it is never     * synchronized.     * If {@code minimumCapacity} is non positive due to numeric     * overflow, this method throws {@code OutOfMemoryError}.     */    private void ensureCapacityInternal(int minimumCapacity) {           // overflow-conscious code        if (minimumCapacity - value.length > 0) {               value = Arrays.copyOf(value,                    newCapacity(minimumCapacity));        }    }
  • 复制方法如下:
/**     * Copies the specified array, truncating or padding with null characters (if necessary)     * so the copy has the specified length.  For all indices that are valid     * in both the original array and the copy, the two arrays will contain     * identical values.  For any indices that are valid in the copy but not     * the original, the copy will contain '\\u000'.  Such indices     * will exist if and only if the specified length is greater than that of     * the original array.     *     * @param original the array to be copied     * @param newLength the length of the copy to be returned     * @return a copy of the original array, truncated or padded with null characters     *     to obtain the specified length     * @throws NegativeArraySizeException if newLength is negative     * @throws NullPointerException if original is null     * @since 1.6     */    public static char[] copyOf(char[] original, int newLength) {           char[] copy = new char[newLength];        System.arraycopy(original, 0, copy, 0,                         Math.min(original.length, newLength));        return copy;    }

可以看到调用的是 System方法,方法如下:

public static native void arraycopy(Object src,  int  srcPos,                                        Object dest, int destPos,                                        int length);

调用的是native的本地方法

  • getChars()方法如下:
/**     * Places characters representing the integer i into the     * character array buf. The characters are placed into     * the buffer backwards starting with the least significant     * digit at the specified index (exclusive), and working     * backwards from there.     *     * Will fail if i == Integer.MIN_VALUE     */    static void getChars(int i, int index, char[] buf) {           int q, r;        int charPos = index;        char sign = 0;        if (i < 0) {               sign = '-';            i = -i;        }        // Generate two digits per iteration        while (i >= 65536) {               q = i / 100;        // really: r = i - (q * 100);            r = i - ((q << 6) + (q << 5) + (q << 2));            i = q;            buf [--charPos] = DigitOnes[r];            buf [--charPos] = DigitTens[r];        }        // Fall thru to fast mode for smaller numbers        // assert(i <= 65536, i);        for (;;) {               q = (i * 52429) >>> (16+3);            r = i - ((q << 3) + (q << 1));  // r = i-(q*10) ...            buf [--charPos] = digits [r];            i = q;            if (i == 0) break;        }        if (sign != 0) {               buf [--charPos] = sign;        }    }

StringBuffer和StringBuilder之间的区别

StringBuffer是线程安全的,因为StringBuffer方法加锁了,而StringBuilder方法没有加锁

StringBuffer对应的方法如下:

@Override    public synchronized int length() {           return count;    }    @Override    public synchronized int capacity() {           return value.length;    }    @Override    public synchronized void ensureCapacity(int minimumCapacity) {           super.ensureCapacity(minimumCapacity);    }    /**     * @since      1.5     */    @Override    public synchronized void trimToSize() {           super.trimToSize();    }    /**     * @throws IndexOutOfBoundsException {@inheritDoc}     * @see        #length()     */    @Override    public synchronized void setLength(int newLength) {           toStringCache = null;        super.setLength(newLength);    }    /**     * @throws IndexOutOfBoundsException {@inheritDoc}     * @see        #length()     */    @Override    public synchronized char charAt(int index) {           if ((index < 0) || (index >= count))            throw new StringIndexOutOfBoundsException(index);        return value[index];    }

StringBuilder对应的方法如下:

@Override    public int indexOf(String str) {           return super.indexOf(str);    }    @Override    public int indexOf(String str, int fromIndex) {           return super.indexOf(str, fromIndex);    }    @Override    public int lastIndexOf(String str) {           return super.lastIndexOf(str);    }    @Override    public int lastIndexOf(String str, int fromIndex) {           return super.lastIndexOf(str, fromIndex);    }    @Override    public StringBuilder reverse() {           super.reverse();        return this;    }
上一篇:LRU算法
下一篇:Springboot事务的实现原理

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2025年03月25日 02时52分36秒