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




kotlin charsequence string (7)

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の正確な違いは、StringがCharSequenceを実装し、 StringStringのシーケンスであるという事実以外は誰でも言うことができますか? 例えば:

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

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


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));
}

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のJava APIから:

CharSequenceは読み取り可能な文字シーケンスです。 このインタフェースは、さまざまな種類の文字シーケンスに対して、一様な読み取り専用アクセスを提供します。

このインタフェースは、 StringCharBuffer 、およびStringBufferによって使用され、すべてのメソッド名の一貫性を保ちます。


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

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


一般的な違い

StringほかにCharSequenceインタフェースを実装するクラスがいくつかあります。 これらの中には

  • 変更可能な可変長文字シーケンスのStringBuilder
  • 変更可能な固定長の低レベル文字シーケンス用のCharBuffer

CharSequenceを受け入れるメソッドは、これらすべてで同様にうまく動作します。 Stringを受け付けるメソッドだけで変換が必要です。 したがって、内部を気にしないすべての場所でCharSequenceを引数型として使用することは賢明です。 実際にString返す場合は、返す型としてStringを使用する必要があります。これは、呼び出し側のメソッドに実際にStringが必要な場合に返される値の変換が行われないようにするためです。

マップはキーを変更してはいけないので、マップはCharSequenceではなく、キータイプとしてStringを使用する必要があります。 言い換えれば、時にはStringの不変の性質が不可欠です。

特定のコードスニペット

あなたが貼り付けたコードについては、単純にコンパイルし、 javap -vを使ってJVMのバイトコードをjavap -v 。 ここで、 objstr両方が同じ定数オブジェクトへの参照であることに気づくでしょう。 Stringは不変なので、この種の共有は大丈夫です。

String+演算子は、さまざまなStringBuilder.append呼び出しの呼び出しとしてコンパイルされます。 したがって、

System.out.println(
  (new StringBuilder())
  .append("output is : ")
  .append((Object)obj)
  .append(" ")
  .append(str)
  .toString()
)

私は、私のコンパイラjavac 1.6.0_33StringBuilder.append(CharSequence)代わりにStringBuilder.append(CharSequence) StringBuilder.append(Object)を使用して+ objをコンパイルするjavac 1.6.0_33少し驚いています。 前者はおそらくオブジェクトのtoString()メソッドを呼び出しますが、後者はより効率的な方法で可能になるはずです。 一方、 String.toString()単にString自体を返しますので、そこにはほとんどペナルティはありません。 だから、 StringBuilder.append(String)は、メソッド呼び出しを1回行うほうが効率的かもしれません。


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

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





charsequence