tl;dr
1 つはインターフェイス ( CharSequence
) で、もう 1 つはそのインターフェイスの具体的な実装 ( String
) です。
CharSequence animal = "cat" // `String` object presented as the interface `CharSequence`.
ArrayList
が であるのとList
同じように、 もです。HashMap
Map
String
CharSequence
インターフェースとしては、通常は よりも のCharSequence
方がよく見られますString
が、ねじれた歴史により、実装から数年後にインターフェースが定義されることになりました。そのため、古い API ではよく見かけますが、新しい API では引数と戻り値の定義に使用されるString
傾向があります。CharSequence
詳細
最近では、一般的に、API/フレームワークは主にインターフェイスのエクスポートに焦点を当て、2 番目に具象クラスに焦点を当てる必要があることがわかっています。しかし、私たちはいつもこの教訓をよく知っていたわけではありません。
String
クラスはJavaで最初に登場しました。後になって初めて、彼らは正面向きのインターフェースを配置しましたCharSequence
.
ねじれた歴史
少しの歴史が理解に役立つかもしれません。
初期の頃、Java は、インターネット/Web マニアが業界を活気づけていたため、時代よりも少し早く市場に投入されました。一部のライブラリは、本来あるべきほどよく考え抜かれていませんでした。文字列の処理は、その分野の 1 つです。
また、Java は、最も初期のプロダクション指向の非アカデミックなオブジェクト指向プログラミング (OOP)環境の 1 つでした。それ以前に成功した実世界のラバー ミート ザ ロード実装は、 SmallTalkのいくつかの限定バージョンであり、その後はNeXTSTEP / OpenStepを使用したObjective-Cでした。そのため、多くの実践的な教訓がまだ習得されていませんでした。
JavaはString
クラスとStringBuffer
クラスから始まりました。しかし、これら 2 つのクラスは無関係であり、継承やインターフェイスによって互いに関連付けられていません。その後、Java チームは、文字列関連の実装を交換可能にするために、それらの間に統一的な関係が必要であることに気付きました。Java 4 では、チームはインターフェイスを追加し、CharSequence
そのインターフェイスを String および String Buffer にさかのぼって実装し、別の実装を追加しましたCharBuffer
。StringBuilder
後にJava 5 で追加されたStringBuffer
.
そのため、これらの文字列指向のクラスは少しごちゃごちゃしていて、学ぶのが少し混乱します。多くのライブラリとインターフェイスは、String
オブジェクトを受け取って返すために構築されました。現在、そのようなライブラリは一般に期待するように構築する必要がありCharSequence
ます。しかし、(a)String
依然としてマインドスペースを支配しているようであり、(b) さまざまなCharSequence
実装を混在させると、微妙な技術的問題が発生する可能性があります。後知恵の 20/20 ビジョンでは、このすべての文字列をより適切に処理できた可能性があることがわかりますが、ここにあります。
理想的には、Java は、またはの実装の代わりにまたはインターフェースString
を使用するのと同じように、現在 を使用している多くの場所で使用されるインターフェースおよび/またはスーパークラスから始めていたはずです。Collection
List
ArrayList
LinkedList
インターフェイスとクラス
主な違いは、実装ではなくインターフェイスCharSequence
であるということです。つまり、 を直接インスタンス化することはできません。むしろ、そのインターフェースを実装するクラスの 1 つをインスタンス化します。CharSequence
たとえば、これx
は のように見えますがCharSequence
、その下には実際にはStringBuilder
オブジェクトがあります。
CharSequence x = new StringBuilder( "dog" ); // Looks like a `CharSequence` but is actually a `StringBuilder` instance.
これは、文字列リテラルを使用すると、あまり明白ではなくなります。文字を引用符だけで囲んでいるソース コードを見ると、コンパイラはそれを String オブジェクトに変換していることに注意してください。
CharSequence y = "cat"; // Looks like a `CharSequence` but is actually a `String` instance.
リテラルとコンストラクター
この他の質問で説明されているように、"cat"
との間にはいくつかの微妙な違いがありますが、ここでは関係ありません。new String("cat")
クラス図
このクラス図が参考になるかもしれません。これらのクラスとインターフェースを通じてどれだけの変更が行われたかを示しているように見える Java のバージョンに注目しました。
テキストブロック
多数のemojiを含むUnicode文字をさらに追加することを除けば、近年 Java でテキストを操作するための変更はあまりありません。テキストブロックまで。
テキスト ブロックは、複数行または文字エスケープを使用した文字列リテラルの退屈な処理を改善する新しい方法です。これにより、HTML、XML、SQL、または JSON などの埋め込みコード文字列の記述がはるかに便利になります。
JEP 378を引用するには:
テキスト ブロックは複数行の文字列リテラルであり、ほとんどのエスケープ シーケンスを必要とせず、予測可能な方法で文字列を自動的にフォーマットし、必要に応じて開発者がフォーマットを制御できるようにします。
テキスト ブロック機能は、新しいデータ型を導入しません。テキスト ブロックは、リテラルを記述するための新しい構文にすぎません。従来のリテラル構文と同様に、テキスト ブロックはオブジェクトを生成します。テキスト ブロックは、上で説明したように、オブジェクトでもあるオブジェクトを生成します。String
String
String
CharSequence
SQL の例
JSR 378 をもう一度引用すると…</p>
「一次元」文字列リテラルの使用。
String query = "SELECT \"EMP_ID\", \"LAST_NAME\" FROM \"EMPLOYEE_TB\"\n" +
"WHERE \"CITY\" = 'INDIANAPOLIS'\n" +
"ORDER BY \"EMP_ID\", \"LAST_NAME\";\n";
「二次元」のテキスト ブロックの使用
String query = """
SELECT "EMP_ID", "LAST_NAME" FROM "EMPLOYEE_TB"
WHERE "CITY" = 'INDIANAPOLIS'
ORDER BY "EMP_ID", "LAST_NAME";
""";
JEP 378: Text Blocksに従って、テキスト ブロックはJava 15以降で検出されます。
JEP 355: Text Blocks (Preview)の下で、Java 13 で最初にプレビューされました。次に、Java 14 でJEP 368: Text Blocks (Second Preview)の下で再度プレビューしました。
この取り組みは、 JEP 326: Raw String Literals (Preview)によって先行されました。代わりに、テキスト ブロック機能を生成するために概念が作り直されました。