比較 - java[duplicate]のCharSequenceとStringの正確な違い




kotlin charsequence string (6)

StringがCharSequenceを実装し、Stringが文字のシーケンスであるという事実以外は、

あなたのコードにはいくつかのことが起こります:

CharSequence obj = "hello";

これはStringリテラル、 "hello"作成します。これはStringオブジェクトです。 CharSequenceを実装するStringであるため、 CharSequenceでもあります。 (例えば、インタフェースについてのコーディングについてこの記事を読むことができます)。

次の行:

String str = "hello";

もう少し複雑です。 JavaのStringリテラルはプール内に保持されているため、この行の"hello"は最初の行の"hello"と同じオブジェクト(ID)です。 したがって、この行はstr同じStringリテラルのみを割り当てstr

この時点で、 objstrStringリテラル"hello"への参照であり、したがってequals==あり、 StringCharSequence両方CharSequence

このコードをテストして、私が書いたものを実際に表示することをお勧めします:

public static void main(String[] args) {
    CharSequence obj = "hello";
    String str = "hello";
    System.out.println("Type of obj: " + obj.getClass().getSimpleName());
    System.out.println("Type of str: " + str.getClass().getSimpleName());
    System.out.println("Value of obj: " + obj);
    System.out.println("Value of str: " + str);
    System.out.println("Is obj a String? " + (obj instanceof String));
    System.out.println("Is obj a CharSequence? " + (obj instanceof CharSequence));
    System.out.println("Is str a String? " + (str instanceof String));
    System.out.println("Is str a CharSequence? " + (str instanceof CharSequence));
    System.out.println("Is \"hello\" a String? " + ("hello" instanceof String));
    System.out.println("Is \"hello\" a CharSequence? " + ("hello" instanceof CharSequence));
    System.out.println("str.equals(obj)? " + str.equals(obj));
    System.out.println("(str == obj)? " + (str == obj));
}

私はこの前の記事を読んでます。 CharSequenceとStringの正確な違いは、StringがCharSequenceを実装し、 StringStringのシーケンスであるという事実以外は誰でも言うことができますか? 例えば:

CharSequence obj = "hello";
String str = "hello";
System.out.println("output is : " + obj + "  " + str);

「こんにちは」がobj割り当てられ、 str再度割り当てられるとどうなりstrか?


tl; dr

一方はインタフェース( CharSequence )であり、otherはそのインタフェース( String )の具象実装です。

CharSequence animal = "cat"  // `String` object presented as the interface `CharSequence`.

インタフェースとして、通常はCharSequenceStringよりも一般的に見られるでしょうが、いくつかのねじれた歴史の結果、実装何年もの間にインタフェースが定義されていました。 古いAPIではStringをよく見ていますが、新しいAPIではCharSequence引数や戻り値の型を定義するのに使用される傾向があります。

詳細

今日では、一般的に、API /フレームワークは主にインターフェースを主に、具体的なクラスを副次的にエクスポートすることに焦点を当てるべきであることが分かっています。 しかし、私たちはいつもこのレッスンをよく知っていませんでした。

StringクラスがJavaで最初に登場しました。 後で、彼らは正面向きのインターフェイスCharSequence

ツイストの歴史

少しの歴史が理解に役立つかもしれない。

初期の段階では、Javaは、インターネット/ Webマニアが業界をアニメーション化するため、その時間より少し先に市場に突入した。 いくつかの図書館は、そうしなければならないような思考通りではありませんでした。 文字列の扱いは、これらの分野の1つでした。

また、Javaは生産指向の非学術オブジェクト指向プログラミング(OOP)環境の中でも最も初期のものの1つでした。 これまでにOOPのSmallTalkラバー・ザ・ロード・インプリメンテーションは、 SmallTalkいくつかの限定されたバージョン、次にNeXTSTEP / OpenStep Objective-Cでした。 だから、多くの実践的な教訓はまだ学ばれていませんでした。

JavaはStringクラスとStringBufferクラスで始まりました。 しかし、これらの2つのクラスは無関係であり、継承やインターフェースによって互いに結ばれていませんでした。 後で、Javaチームは、文字列関連の実装間で統一的な結びつきがあって、それらを交換可能にする必要があることを認識しました。 Java 4では、チームはCharSequenceインターフェースを追加し、そのインターフェースをStringとString Bufferに遡及的に実装し、別の実装CharBufferを追加しました。 Java 5の後半で、 StringBuilderを追加しました。これは、基本的に非同期で、したがって、いくぶん高速なStringBufferバージョンです。

だから、これらの文字列指向のクラスはちょっと混乱していて、少し紛らわしいことが分かります。 Stringオブジェクトを取得して返すために、多くのライブラリとインタフェースが構築されていました。 今日、このようなライブラリは一般的にCharSequenceを期待するように構築されるべきCharSequence 。 しかし、(a) Stringはまだマインドスペースを支配しているようですが、(b)さまざまなCharSequence実装を混在させると、若干の技術的問題があるかもしれません。 私たちは20/20のビジョンのビジョンをもって、この文字列のすべてがよりうまく処理されていることが分かりましたが、ここにはあります。

理想的には、Javaは、 ArrayListまたはLinkedList実装の代わりにCollectionまたはListインタフェースを使用するのと同じように、 Stringが使用される多くの場所で使用されるインタフェースおよび/またはスーパークラスから始めるのが理想的ArrayList

インターフェイス対クラス

CharSequenceの主な違いは、それがimplementationではなくinterfaceであるimplementationです。 つまり、 CharSequence直接インスタンス化することはできません。 むしろ、そのインタフェースを実装するクラスの1つをインスタンス化します。

たとえば、ここではCharSequenceように見えるxがありますが、実際はStringBuilderオブジェクトです。

CharSequence x = new StringBuilder( "dog" );

これは、文字列リテラルを使用するときにはあまり明らかになりません。 文字の前後に引用符だけがあるソースコードを見ると、コンパイラはそれをStringオブジェクトに変換しています。

CharSequence y = "cat";  // Looks like a CharSequence but is actually a String instance.

この他の質問で議論されているように"cat"new String("cat")間には若干の違いがありますが、ここでは無関係です。

クラス図

このクラス図はあなたを導くのに役立ちます。 私はJavaのバージョンに注目しました。Javaのバージョンでは、これらのクラスとインタフェースをどの程度変更したかを示すように見えました。


UTF-8を検討してください。 UTF-8 Unicodeコードポイントは、1つ以上のバイトから構築されます。 UTF-8バイト配列をカプセル化するクラスは、CharSequenceインターフェイスを実装できますが、文字列ではありません。 確かに、Stringが必要なUTF-8バイト配列を渡すことはできませんが、契約が緩和されてCharSequenceが可能な場合は、CharSequenceを実装するUTF-8ラッパークラスを確実に渡すことができます。 私のプロジェクトでは、xmlのデータ圧縮を提供するためにCBTF8Field(Compressed Binary Transfer Format - Eight Bit)というクラスを開発しており、CharSequenceインターフェイスを使用してCBTF8バイト配列から文字配列(UTF-16)への変換を実装しようとしています)とバイト配列(UTF-8)です。

私がここに来た理由は、サブシーケンス契約の完全な理解を得ることでした。


charSequenceでは、Stringに利用できる非常に便利なメソッドはありません。 ドキュメントを見たくない場合は、objをタイプしてください。 とstr。

あなたのコンパイラがどのような方法であなたを提供しているかを見てください。 それが私の基本的な違いです。


CharSequenceは契約( interface )であり、 Stringはこの契約のimplementationです。

public final class String extends Object 
    implements Serializable, Comparable<String>, CharSequence

CharSequenceCharSequenceは次のとおりです。

CharSequenceは、char値の読み取り可能なシーケンスです。 このインタフェースは、さまざまな種類のcharシーケンスに対して一様な読み取り専用アクセスを提供します。 char値は、Basic Multilingual Plane(BMP)の文字または代理文字を表します。 詳細については、Unicode Character Representationを参照してください。


私はそれが一種の明白なことを知っていますが、CharSequenceはインターフェイスですが、Stringは具体的なクラスです:)

java.lang.Stringはこのインタフェースの実装です...





charsequence