String Buffer 和 String Build学习笔记

public class Concatenation {
  public static void main(String[] args) {
    String mango = "mango";
    String s = "abc" + mango + "def" + 47;
    System.out.println(s);
  }
} /* Output:
abcmangodef47
*///:~

引入一段代码,大家都知道“+”与“+=”操作符是java中仅有的两个重载过的操作符(java并不允许程序员重载任何操作符),“+”可以用来连接String,如上述代码所示。

可能大家都知道这段代码是怎么工作的,按照编程思想书中的描述,可以用JDK自带的工具javap来反编译上述代码,命令如下:javap -c Concatenation 这里的“-c”表示将生成JVM代码。我跑了一下结果如下:

public class Concatenation {
  public Concatenation();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":
()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: ldc           #2                  // String mango
       2: astore_1
       3: new           #3                  // class java/lang/StringBuilder
       6: dup
       7: invokespecial #4                  // Method java/lang/StringBuilder."<
init>":()V
      10: ldc           #5                  // String abc
      12: invokevirtual #6                  // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      15: aload_1
      16: invokevirtual #6                  // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      19: ldc           #7                  // String def
      21: invokevirtual #6                  // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      24: bipush        47
      26: invokevirtual #8                  // Method java/lang/StringBuilder.ap
pend:(I)Ljava/lang/StringBuilder;
      29: invokevirtual #9                  // Method java/lang/StringBuilder.to
String:()Ljava/lang/String;
      32: astore_2
      33: getstatic     #10                 // Field java/lang/System.out:Ljava/
io/PrintStream;
      36: aload_2
      37: invokevirtual #11                 // Method java/io/PrintStream.printl
n:(Ljava/lang/String;)V
      40: return
}

据说有汇编语言经验的看着会觉得眼熟,这里的重点就是编译器自动引入了java.lang.StringBuilder类,虽然源码并没有使用StringBuilder类,但是编译器自作主张地使用了它,因为它更高效。

StringBuilder是java SE5引入的,如果看源码会注意到这样一段注释

 * @author      Michael McCloskey
 * @see         java.lang.StringBuffer
 * @see         java.lang.String
 * @since       1.5
 */
public final class StringBuilder

since 1.5,那么在这之前java用的是什么呢,就是StringBuffer。

 * @author      Arthur van Hoff
 * @see     java.lang.StringBuilder
 * @see     java.lang.String
 * @since   JDK1.0
 */
 public final class StringBuffer

1.0就已经有了,而且是线程安全的,因此开销也会大些,所以在java SE5/6中(现在已经到8了),字符串的操作应该还会更快一些。

看过源码就会发现,注释的第一句话就对线程是否安全做了说明

/*
 * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package java.lang;

import java.util.Arrays;

/**
 * A thread-safe, mutable sequence of characters.
 * A string buffer is like a {@link String}, but can be modified. At any
 * point in time it contains some particular sequence of characters, but
 * the length and content of the sequence can be changed through certain
 * method calls.

看看源码就会发现,StringBuffer类的很多方法都是用了synchronized关键字声明,而StringBuilder并没有,StringBuilder属于非线程安全。

StringBuffer和StringBuilder的父类都是AbstractStringBuilder,他们的构造方法都是调用父类的构造方法

/**
     * Constructs a string buffer with no characters in it and an
     * initial capacity of 16 characters.
     */
    public StringBuffer() {
        super(16);
    }
  /**
     * Constructs a string builder with no characters in it and an
     * initial capacity of 16 characters.
     */
    public StringBuilder() {
        super(16);
    }
    /**
     * Creates an AbstractStringBuilder of the specified capacity.
     */
    AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }


你可能感兴趣的:(String Buffer 和 String Build学习笔记)