8

JavaStringBuilderとの違いは十分に文書化されており、StackOverflowでも触れられています。StringBuffer

基本的に、StringBuilderはの非同期コピーでありStringBuffer、のより高速なドロップイン置換として意図されていたため、ほとんど同じインターフェイスを備えていますStringBuffer。それらのAPIは実質的に同一であり、実際には現在のJDKの同じアクセスできない抽象クラスのサブクラスです。

したがって、私が疑問に思うことの1つは、なぜそれらが公に関連していないのかということです。両方のクラスに共通のインターフェースを実装させるかStringBuffer、のサブクラスとして持つStringBuilderことは理にかなっており、両方のクラスの共有コードの存在を可能にします。

では、なぜこの強制分離なのか?プログラマーが誤ってスレッドセーフなコードとスレッドセーフでないコードを混同しないようにするためでしたか?それとも、今や永遠の終わりまで受け継がれるのは、単なる設計の見落としだったのでしょうか。

編集:

明確にするために:私は物事がこのようなものである理由を推測することができますが、たとえばJSRプロセス中など、実際の決定への具体的な参照を望んでいます。私にとって、何が何かに光を当てるであろうものは、時々ある程度の困難を引き起こす状況です。

編集2:

両方のクラスが実装されているという事実はAppendable、私の心を完全に滑らせました。おそらく、その特定のインターフェイスはほとんどの目的で役に立たないためです。追加できるのは1つの文字または準備されたオブジェクトのみであり、それだけです。ほとんどの場合、両方のクラスがのサブクラスであるよりも便利ではありませんObject

編集3:

さて、これが半公式の情報源からのまさにこの質問の理論的根拠です:

図書館チームによる評価:

StringBufferとStringBuilderが共通のパブリックスーパータイプを共有しないのは設計によるものです。それらは代替を意図したものではありません。1つは間違い(StringBuffer)であり、もう1つ(StringBuilder)はその置き換えです。

明らかに、一般的なスーパータイプがないため、場合によっては、StringBufferからStringBuilderへの期待される移行が遅くなる可能性があります。反対に、共通のスーパータイプを追加することで、過去のエラーを取得し、パブリックインターフェイスにそれらを祀って常に一緒にいることになります。これは単に移行を遅らせるだけでなく、移行を狂わせます。

4

2 に答える 2

3

私はJSRリファレンスを持っていませんが、私の経験からです。以下はいくつかの理由です:

  • StringBufferサブクラスStringBuilder 、パフォーマンス上の理由からお勧めできません。スレッドセーフにするためには、オーバーヘッドの多いStringBufferすべての呼び出しをマスクする必要があります。StringBuilder

  • 上記の点に加えて、JavaがAPIに追加された理由であるクラスの内部に直接アクセスできる場合は、さらに最適化できます。より直接的なアクセスにより、最適化のためのより多くのオプションが提供されます。この点をサポートするにはIBMブログからの参照java.lang.concurrentjava.util.Collections.synchronized*

  • さらに最初のポイントに加えて、両方のクラスが非常に確実にこれらのクラスをサブクラス化することを望まないため、これは設計上の見落としではないと思います。final

  • 同じインターフェースに関しては、両方のクラスが同じインターフェースを実装しますSerializable, Appendable, CharSequence。したがって、それらはドロップイン代替品です。唯一のことは、それらが1つの共通インターフェースではなく、3つの共通インターフェースを実装していることです。技術的には現在のインターフェイスの合計になる肥大化したインターフェイスを1つ持つ必要がないため、これは理にかなっています(Serializable, Appendable, CharSequence)。

編集:

  • @MatthewFlaschenが指摘するように、b / wは同じであるが、実装されているインターフェイスのいずれにも存在しないAPIがStringBufferあります。StringBuilderこれは、下位互換性と関係があります。新しいAPIを追加したいのですが、インターフェースは他の多くのクラスで使用されているため、インターフェースを変更することは現実的ではない可能性があります。これは、Javaの人たちが下したかもしれない決定についてよく考えられています。だから私はそれが間違いだとは言いません。

編集2:

サイドノート:もう1つ注意すべき点はStringBuffer、1.0とStringBuilder1.5で導入されたことです。したがって、両方のクラスに存在するがインターフェイスには存在しないAPIは、後で導入され、これらのクラスの作成時には導入されません。

于 2012-03-19T03:39:55.920 に答える
2

それらは実際には両方を実装しAppendableます。

これが役に立たないことに同意しません。私の経験では、StringBuilder / StringBufferの使用の大部分は、(を実装するCharSequence)文字列を処理するだけです。String.valueOf残りの部分については、渡す前に呼び出すことができます。

のような他のメソッドも持つ別のインターフェースがあれば便利ですappend(long)。しかし、それは必須ではありません。

共通のインターフェースを持つことは合理的でしょう。それらは異なるパフォーマンスとスレッド特性を持っていますが、それはJDKの多くのインターフェースに当てはまります。

たとえばCopyOnWriteArrayList、配列ベースのスレッドセーフリスト(書き込みごとに新しいリストを作成します)では、LinkedListスレッドセーフではないリンクリストです。

于 2012-03-19T03:14:42.930 に答える