12

これらの宣言は互いにどのように異なっていますか?

String s="MY PROFESSION";
char c[]="MY PROFESSION";

それぞれの場合のメモリ割り当てはどうですか?

4

7 に答える 7

13

char[]コンパイル エラーを修正するには、次のいずれかのステートメントに置き換えます

String s = "MY PROFESSION";
char c1[] = "MY PROFESSION".toCharArray();
char c2[] = { 'M', 'Y', ' ', 'P', 'R', 'O', 'F', 'E', 'S', 'S', 'I', 'O', 'N' };
StringBuilder sb = new StringBuilder("MY PROFESSION");
StringBuffer sbu = new StringBuffer("MY PROFESSION");

次のセクションでは、上記のステートメントを相互に比較します

文字列定数

String s="MY PROFESSION";

文字配列

 char c1[]="MY PROFESSION".toCharArray();
 char c2[]={'M', 'Y', ' ', 'P', 'R', 'O', 'F', 'E', 'S', 'S', 'I', 'O', 'N'};
  • c1String の基になる配列のコピーを ( 経由でSystem.arraycopy) 保持し、ヒープ領域に格納します
  • c2個々の文字定数をロードすることにより、スタック フレームにその場で構築されます。
  • c1&c2は変更可能です。つまり、内容を変更Arrayできます。c2[0]='B'
  • 配列のサイズ・長さは固定(追加不可)

StringBuilder / StringBuffer

StringBuilder sb = new StringBuilder("MY PROFESSION");
StringBuffer sbu = new StringBuffer("MY PROFESSION");
  • sbとは両方ともsbu変更可能です。sb.replace(0, 1, 'B');
  • sbとの両方sbuがヒープに格納されます
  • サイズ/長さは変更可能です。sb.append( '!');
  • StringBufferのメソッドは同期されていますが、 のメソッドは同期さStringBuilderれていません
于 2013-08-17T13:34:34.267 に答える
4

最初のものはコンパイルされます。2番目のものはそうではありません。

Achar[]はまさに、char 型のプリミティブ数の配列です。提供されるのは、length属性と、特定のインデックスで char を取得および設定する方法だけです。

String はjava.lang.String型のオブジェクトで、Stringを操作するための便利なメソッドがたくさんあります。内部的には、char 配列を使用します。

String のもう 1 つの重要な機能は、不変であることです。String は任意のメソッドに渡すことができ、このメソッドが String の内容を変更しないことを確認してください。char 配列の場合はそうではありません。

メモリに関しては、String はより多くのバイトを消費しますが、それは通常、設計上の決定を導くべきものではありません。一般に、char 配列を使用することはすべきことではありません。

于 2013-08-17T12:31:28.823 に答える
1

文字の配列は変更可能です。つまり、文字のメモリ位置を上書きすることで、文字の配列内の文字を置き換えることができます。

文字列は可変ではありません。つまり、文字列内の文字を「置き換える」には、目的の文字を配置して新しい文字列を作成する必要があります (古い文字列から変更されていない部分をコピーします)。

これは単純に思えますが、スレッド (およびオブジェクト) 間で共有する機能に大きな影響を与えます。1 つの文字列は、文字列が変更されているかどうかを確認する追加のチェックを行わなくても、スレッド間で安全に共有できます (これにより、スレッドに文字列の読み取りの不一致が生じる可能性があります)。

文字列は変更できないため、他の最適化も可能です。等価演算を「値による等価」に再配線できます。つまり、「String factory」は、2 つの異なる String オブジェクトが要求された場合でも、同じ String のキャッシュされたコピーを返すことができます。これは、2 つのオブジェクトが異なる動作をすることが不可能になるためです。

于 2013-08-17T14:02:49.990 に答える
1

ドキュメントを見ると、

     String str = "abc";

is equivalent to:

     char data[] = {'a', 'b', 'c'};  //  not 'abc'
     String str = new String(data);

さらに、文字列リテラルはJavaでは非常に特別です

Stringcharacter内部的に配列に支えられています。

于 2013-08-17T12:30:31.180 に答える
0

この宣言は互いにどのように区別されますか?

最初の行でStringインスタンスが生成されます。2行目は単に無効です。おそらくあなたは次のことを意味しました:

char[] c = {'M', 'Y', ' ', 'P', 'R', 'O', 'F', 'E', 'S', 'S', 'I', 'O', 'N'};

char[]それらの文字でいっぱいを作成します。

そのメモリ割り当てはどうですか?

文字列を として保存Stringすることは、 として保存することとメモリの観点からわずかに異なりますchar[]。ただし、類似点があります。どちらもオブジェクトであり、通常のオブジェクト オーバーヘッドがあります。

ただし、 aは内部Stringで aを保持するため、当然、より多くのメモリを消費します。さらに、 には 3 つのフィールド ( 、および) がありますが、フィールドは 1 つしかありません。char[] StringStringintoffsetcounthashchar[]intlength

たとえば、次のように保存"MY PROFESSION"しますString

  • 3intフィールド: 12バイト
  • char[]フィールド: 8バイト
    • intフィールド: 4バイト
    • オブジェクトのオーバーヘッド: 8バイト
    • 13文字:26バイト
  • オブジェクトのオーバーヘッド: 8バイト

これは約66バイトになります。これの一部は VM に依存しているため、「約」と言います。char[]ご覧のとおり、長さ 10の対応するものは38バイトしか消費しません。ここでのメモリの違いはごくわずかなので、気にする必要はありません ( String! を使用するだけです)。保存しようとしている文字列が長くなればなるほど、それはさらに重要ではなくなります。

于 2013-08-17T12:33:41.177 に答える
0

charプリミティブ型です。String実際のデータが文字配列として内部に格納されるクラスです

char c[]="MY PROFESSION";

コンパイルエラーになります。

文字配列は、文字が順番に格納されるメモリ内の連続ストレージです。

詳細については、このスレッドを確認してください。

于 2013-08-17T12:27:36.733 に答える