深さ分析StringBuilderの文字列に置き換えることができます

I.背景

「StringBuilderの」「文字列」に置き換えることができます:StringBuilderの文字列のステッチを使用している場合、コードを書くとき、IDEAは、次のヒントを与えることを可能性があります。

なぜ手がかりを与えますか?何がこの平均を促し?

第二に、だと思います

「すべての質問の背後に少なくとも一つのブラインドスポットと学ぶための絶好の機会を隠されています。」:そこは、前の話されています したがって、我々は簡単にこの機会を手放すことはありません。

また、多くの人が、この時間は、百度をアップし始めるかもしれません!

ストップ!

「」アリ・ババのJava開発マニュアル「コメント印象がより深いとなりますのでことなど、ソースコードの学習に大きな助けと、最初の推測思考検証」「欄には、そこに記載されています」。

ヒント:「StringBuilderのは」で置き換えることができます 「文字列」、 この場合で説明ができるStringBuilder置き換えますString

私たちは、使用が理由を知っているStringBuilder文字列の連結処理が不要文字列オブジェクトの多くを生成しないようにすることですが。

それを交換することができるのでString、この場合で説明することができるどちらも、すなわち底部が同じである、と等価です。

第三に、分析

「」アリ・ババのJava開発マニュアル「コメント」欄には、DEMO、逆コンパイルを書くことについて話しましたがされている逆アセンブルは学習の重要な手段です。

あなたはそれの下でDEMO直接検証を書くこと:

public class StringDemo {

    public static void main(String[] args) {
        String a = "a";
        Integer b = 0;
        Long c = 1000L;
        useStringBuilder(a, b, c);
        usePlus(a, b, c);
    }

    /**
     * 使用 StringBuilder 拼接
     */
    private static void useStringBuilder(String a, Integer b, Long c) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(a).append(b).append(c);
        System.out.println(stringBuilder.toString());
    }

    /**
     * 直接使用+号进行字符串拼接
     */
    private static void usePlus(String a, Integer b, Long c) {
        System.out.println(a + b + c);
    }

}
复制代码

使用IDEAは、逆コンパイラを来て、ほぼ同じソースが(ここでは与えられていない)ことがわかりました。

逆アセンブルへ次の試行javap -c -p StringDemo(以前のjavacでコンパイルされています):

public class com.chujianyun.common.str.StringDemo {
  public com.chujianyun.common.str.StringDemo();
    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 a
       2: astore_1
       3: iconst_0
       4: invokestatic  #3                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       7: astore_2
       8: ldc2_w        #4                  // long 1000l
      11: invokestatic  #6                  // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
      14: astore_3
      15: aload_1
      16: aload_2
      17: aload_3
      18: invokestatic  #7                  // Method useStringBuilder:(Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Long;)V
      21: aload_1
      22: aload_2
      23: aload_3
      24: invokestatic  #8                  // Method usePlus:(Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Long;)V
      27: return

  private static void useStringBuilder(java.lang.String, java.lang.Integer, java.lang.Long);
    Code:
       0: new           #9                  // class java/lang/StringBuilder
       3: dup
       4: invokespecial #10                 // Method java/lang/StringBuilder."<init>":()V
       7: astore_3
       8: aload_3
       9: aload_0
      10: invokevirtual #11                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      13: aload_1
      14: invokevirtual #12                 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      17: aload_2
      18: invokevirtual #12                 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      21: pop
      22: getstatic     #13                 // Field java/lang/System.out:Ljava/io/PrintStream;
      25: aload_3
      26: invokevirtual #14                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      29: invokevirtual #15                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      32: return

  private static void usePlus(java.lang.String, java.lang.Integer, java.lang.Long);
    Code:
       0: getstatic     #13                 // Field java/lang/System.out:Ljava/io/PrintStream;
       3: new           #9                  // class java/lang/StringBuilder
       6: dup
       7: invokespecial #10                 // Method java/lang/StringBuilder."<init>":()V
      10: aload_0
      11: invokevirtual #11                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      14: aload_1
      15: invokevirtual #12                 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      18: aload_2
      19: invokevirtual #12                 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      22: invokevirtual #14                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      25: invokevirtual #15                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      28: return
}
复制代码

注:あなたはまた、列に使用できる最初の記事のスナックは、ビューのバイトコードバイトコードにjclasslibプラグインをお勧めします

私たちは、比較することができますusePlus機能とuseStringBuilderバイトコード命令は、スプライシングテープの機能+可変数は、最終的には、文字列のスプライシングのStringBuilderに変換されますでしょう。

同等のコンパイラの最適化は、そう同等に、IDEAは、コードをよりコンパクトにするために、検出され、それがヒントを与えます。

再び私たちは、「Java言語仕様」開いたら、このアイデアを証明するために15.18.1文字列連結演算子+を。

実装が作成した後、中間廃棄を回避するために、1つのステップで変換及び連結を行うことを選択することができる String オブジェクト。繰り返される文字列連結のパフォーマンスを向上させるために、Javaコンパイラを使用することができる StringBuffer 中間体の数低減するクラスまたは類似の技術を String 、式の評価によって作成されたオブジェクトを。

Java言語は、最初に作成し、文字列オブジェクトの中央を破棄しないようにするために、1つのステップで変換し、スプライシングを実行するために選択することができます。文字列連結演算子のパフォーマンスを向上させるために、Javaコンパイラは、計算式作成された中間Stringオブジェクトの数を減らすために機能StringBuilderクラスまたは同様の技術を使用することができます。

そこで問題は完全に明らかになりました。

IVの概要

そこに書いているの前に「なぜバイトコードを学ぶために皆をお勧めしなければならない」「すべての質問には、少なくとも一つのブラインドスポットと学ぶための絶好の機会を背後に隠されている」 2件の記事を。私はあなたが本当にバイトコードを学習の有用性を理解することを願って、バーバラは、知識の徹底把握し、各質問の詳細な探査を通じて、すべての疑問をつかむことができます。また、強く、彼らはより包括的でより多くの権威ある「Java仮想規範」「Java言語仕様」と見てすることをお勧めいたします。

私は、これはあなたを助けることができると思います。私のコラムへようこそ注意、何か問題がある場合は、私と通信したい、コメントを残すことを歓迎します。

おすすめ

転載: juejin.im/post/5e47d49f51882549052f3a6f