Stringのまとめ

4434 ワード

String基本特性
String:文字列で、「」のペアで表されます.
Stringはfinalとして宣言されています.、継承不可
StringはSerializeableインタフェースを実現しました.文字列がシーケンス化をサポートしていることを示します.Comparableインタフェースが実装されました:Stringがサイズを比較できることを示します
Stringはjdk 8および以前の内部でfinal char[]valueを定義して文字列データを格納する.jdk 9でbyte[]に変更
Stringストレージ構造変更
Stringはbyte[]に符号化タグを付けてメモリスペースを節約
StringBufferとStringBuilderにも対応する変更があります.
Stringの基本特性
Stringは不変の文字列、すなわち不変性を表す
  • 文字列に値を再割り当てする場合は、指定したメモリ領域の値を書き換える必要があり、元のvalueを使用して値を割り当てることはできません.
  • 既存の文字列を連続的に操作する場合、メモリ領域の割り当てを再指定する必要があり、既存のvalueを使用して
  • を割り当てることはできない.
  • Stringのreplace()メソッドを呼び出して指定文字または文字列を変更する場合も、メモリ領域の割り当てを再指定する必要があり、既存のvalueを使用して割り当てられない
  • .
  • 文字列には、newとは異なる文字列量で値が割り当てられ、文字列値が文字列定数プールに宣言されます.

  • 文字列定数プールには、同じ内容が格納されない文字列です.
    StringのString Poolは固定サイズのHashtableで、デフォルト値のサイズ長さは1009ですが、String Poolに入れるStringが非常に多いとHashが衝突してチェーンテーブルが長くなり、チェーンテーブルが長くなるとStringが呼び出されます.internでは性能が大幅に低下します.
    -X:StringTableを使用してStringTableの長さを設定します.
    jdk 6ではStringTableが固定されていて1009の長さなので、定数プールの文字列が多すぎると効率が急速に低下します.StringTable Size設定には必要ありません
    jdk 7では、StringTableの長さのデフォルト値は60012で、jdk 8から1009が設定可能な最小値です.
    Stringのメモリ割当て
    Java 6以降、文字列定数プールは永続世代に格納されます.
    Java 7のOracleのエンジニアは、文字列プールの論理を大きく変更し、文字列定数プールの位置をJavaスタック内に調整します.
  • のすべての文字列はスタック(Heap)に保存され、他の一般的なオブジェクトと同様に、スタックサイズを調整するだけでアプリケーションを最適化できます.
  • 文字列定数プールの概念はもともと多く使われていたが、この変更によりjava 7でStringを再利用する十分な理由がある.intern().

  • Java 8メタ空間、文字列定数がスタックされています.
    Stringの基本操作
    Java言語仕様では、完全に同じ文字列の字面量が要求され、同じUnicode文字シーケンス(同じコードポイントシーケンスを含む定数)を含み、同じStringクラスのインスタンスを指す必要があります.
    文字列の結合
  • 定数と定数の接合結果は定数プールであり、コンパイル期間最適化
  • が原理である.
  • 定数プールに同じ内容の定数が存在しない
  • 変数の1つが変数である限り、結果はスタックにあります.変数接合の原理はStringBuilder
  • です.
  • パッチの結果がintern()メソッドを呼び出すと、定数プールにまだ存在しない文字列オブジェクトがアクティブにプールに格納され、オブジェクトアドレスが返されます.
  • @Test
    public void test3(){
        String s1 = "a";
        String s2 = "b";
        String s3 = "ab";
        /*
           s1 + s2      :(  s       )
        ① StringBuilder s = new StringBuilder();
        ② s.append("a")
        ③ s.append("b")
        ④ s.toString()  -->     new String("ab")
    
          : jdk5.0      StringBuilder, jdk5.0      StringBuffer
         */
    /*
    1.               StringBuilder!
                             ,          ,  StringBuilder   。
    2.    final   、  、      、            ,    final        。
     */
    /**
     *       s               ?
     *      :
     *    : String s = "shkstart";//        
     *    :   intern()
     *         String s = new String("shkstart").intern();
     *         String s = new StringBuilder("shkstart").toString().intern();
     *
     */
    public class StringIntern {
        public static void main(String[] args) {
    
            String s = new String("1");
            s.intern();//       ,            "1"
            String s2 = "1";
            System.out.println(s == s2);//jdk6:false   jdk7/8:false
            String s3 = new String("1") + new String("1");//s3        :new String("11")
            //          ,       ,    "11" ?  :   !!
            s3.intern();//          "11"。    :jdk6:         "11",       。
            //         jdk7:          "11",            new String("11")   
            String s4 = "11";//s4       :              ,        "11"   
            System.out.println(s3 == s4);//jdk6:false  jdk7/8:true
        }
    }
    public class StringIntern1 {
        public static void main(String[] args) {
            //StringIntern.java      :
            String s3 = new String("1") + new String("1");//new String("11")
            //          ,       ,    "11" ?  :   !!
            String s4 = "11";//            "11"
            String s5 = s3.intern();
            System.out.println(s3 == s4);//false
            System.out.println(s5 == s4);//true
        }
    }

    Stringのintern()の使用をまとめる
    Jdk1.6で、この文字列オブジェクトをシリアルプールに挿入しようとします.
  • シリアルプールにある場合は入れず、既存のシリアルプールのオブジェクトのオブジェクトアドレス
  • を返す.
  • がない場合、このオブジェクトは1部付与され、シリアルプールに格納され、シリアルプールのオブジェクトアドレス
  • に戻る.
    jdk1.7から、この文字列オブジェクトアドレスをシリアルプールに入れてみます
  • シリアルプールにある場合は、入れません.既存のシリアルプール内のオブジェクトのアドレス
  • を返す.
  • がない場合、オブジェクトの参照アドレスがコピーされ、シリアルプールに格納され、シリアルプールの参照アドレスが返されます.

  • 参考資料:宋紅康JVM教程