String、StrigBurer、StrigBuiderの違いと使用

4640 ワード

不可変クラス-String
これまで通り勉強する前に、まず関連の定義を見ましょう。以下はJavaDocsから引用します。
Strings are constant;their values cannot be changed after they are created
Stringクラスは可変ではなく、Stringオブジェクトの値は作成後に変更されません。言い換えれば、私たちは普段Stringオブジェクトに対して動作していますが、実際には新しいStringオブジェクトを作成し、そのオブジェクトの参照を私たちのオブジェクトに与えています。メモリの中には元の2つの文字列が残っています。ちょっと回りくどいかもしれませんが、下のコードを見てもいいです。
public class Demo {
    public static void main(String[] args) {
        String str;
        String changeStr;

        str = "chaos";
        changeStr = "";

        System.out.println("  ");
        System.out.println(str);
        System.out.println(changeStr);

        changeStr = change(str);
        System.out.println("   ");
        System.out.println(changeStr);
        System.out.println(str);
    }

    private static String change(String str){
        str = str  + "change";
        return str;
    }
}
出力:
初期チャオ
変更後のchaoschange chaos
私たちはchange()方法がtestの値を変えていないことを見ることができます。なぜですか?実は、change()メソッドに伝えられたのは引用のコピーです。元のオブジェクトはパラメータとして修正されていません。
だから、Stringは大きな穴を持っています。もしString類のこの特性に気付かなかったら、頻繁に変更される文字列のオブジェクトタイプをStringに選択すると、メモリは必ずこの影響を受けて、システム性能に影響を与えます。また、引用が多すぎると、ゴミ回収メカニズムが出発し、性能に影響を与えます。
スレッド安全のSteringBuffer
A thread-safe,mutble sequence of characters.A string buffer is like a String,but can be modified.
StringBufferとStringの最大の違いは、StringBufferは可変クラスであり、言い換えれば、String Bufferの値は変更できるだけでなく、String類の副作用も発生しないことである。また、SteringBufferはスレッドが安全です。たとえば:
public class Demo {
    public static void main(String[] args) {
        String str;

        StringBuffer sb = new StringBuffer();
        StringBuffer changeSb = new StringBuffer();

        str = "chaos";
        sb.append(str);

        System.out.println("  ");
        System.out.println(sb.toString());

        changeSb = sb;
        changeSb.append("change");
        System.out.println("   ");
        System.out.println(sb.toString());
        System.out.println(changeSb.toString());
    }
}
出力:
初期chaosが変わったらchaoschange chaoschange
したがって、我々のプログラムに頻繁に値を修正する必要がある文字列があれば、SteringBufferを使用したほうがいいです。先ほど述べた「スレッドセキュリティ」と「可変」の2つの特性のほかに、StringBufferごとに一定のバッファ容量があります。文字列のサイズが容量上限を超えると容量が増加します。
このように見ると、多くの人がシュリングバッファerを完璧だと思って、後で使います。このような学友に対して私は1つ言いたいです:しばらく!実際には、StringBufferは完璧に見えますが、スレッドの安全実現メカニズムは最大の弱点です。まず、スレッドの安全はどのように実現されているかを見てみます。
@Override
    public synchronized StringBuffer append(boolean b) {
        toStringCache = null;
        super.append(b);
        return this;
    }
StringBufferがsynchronizedをキーワードに同期ロックをかけてスレッドの安全を実現することが見られます。しかし、もし私たちがapped 1 wを行うと、プログラムは1 wのロック解除による時間の消費を負担し、効率に影響を与えます。また、ほとんどの場合、私たちはシングルスレッドでStringを使用しています。スレッドの安全問題を考慮する必要はありません。これにより、StringBufferのロック/アンロックプロセスはプログラムに不要な費用をもたらします。だからEffective Javaにはこんな言葉があります。
Java 1.5のリリースでは、同期されていないStringBuiderクラスが追加され、現在は古いStringBufferクラスに代わっています。
スレッド以外の安全なStringBuider
実際には、StringBuiderの内部実装とStringBufferはほぼ同じで、唯一の違いは、StringBuiderの中でsynchronizedのキーワードを取り除いてスレッドの安全性を失ったことにある。
先ほども述べましたが、StringBufferのスレッドセキュリティメカニズムはほとんどの場合必要ではなく、システムによるオーバヘッドは全く必要ではないので、Java 1.5のリリース版はStringBuiderを発売しました。
他の点では区別がないので、SteringBuilderを使うべきです。スレッドの安全問題を考慮してSteringBufferを考慮したり、Stering Builderを書き直したりする方法でスレッドの安全を実現します。