2

メソッドがあるとします:

public String getString() {
    char[] array = new char[]{'a', 'b', 'c'};
    return new String(array);
}

配列は引き続き String コンストラクターでコピーされますか?それとも Java コンパイラーは、配列内の要素が変更できないことを認識して、配列を参照するだけでよいのでしょうか?

ありがとう

4

5 に答える 5

6

JavaStringクラスは不変であるため、コンストラクターは配列をコピーする必要があります。

それ以外の場合は、誰かが配列への参照を保持して変更できます。

char[] array = new char[]{'a', 'b', 'c'};
String string = new String(array);

array[1] = 'd'; // array modification must NOT affect the string
于 2013-09-12T13:38:37.047 に答える
4

のソースを参照してくださいjava.lang.String:

/**
 * Allocates a new {@code String} so that it represents the sequence of
 * characters currently contained in the character array argument. The
 * contents of the character array are copied; subsequent modification of
 * the character array does not affect the newly created string.
 *
 * @param  value
 *         The initial value of the string
 */
public String(char value[]) {
    this.value = Arrays.copyOf(value, value.length);
}

編集

java.util.Arrayswhich 呼び出しのソースも参照してくださいSystem.arraycopy

于 2013-09-12T13:37:46.007 に答える
1

答えは明らかです。String不変のままであるためには、防御的に配列をコピーする必要があります。

次のコードを検討してください。

public String getString() {
    char[] array = new char[]{'a', 'b', 'c'};
    String s = new String(array); // abc
    array[0] = 'x';
    return s; // xbc 
}

配列がコピーされていない場合、バッキング配列がリークされ、文字列が可変性にさらされます。

于 2013-09-12T13:41:02.017 に答える
1

このコンストラクターも見てください。

  153     public String(String original) {
  154         this.value = original`.value;
  155         this.hash = original.hash;
  156     }

これは文字列リテラルになります。

"abc"

String(char[] value)これは、char 配列の要素として渡された a、b、c を使用した単なる呼び出しです。要するに、String x = "abc"上記の処理を回避するためにコンパイラが提供する単なる構文糖衣です。

于 2013-09-12T13:41:40.423 に答える
0

ソースコードを見れば答えが出ます。入力配列はコピーされ、参照されません。ソースコードは次のとおりです。

public String(char value[]) {
this.offset = 0;
this.count = value.length;
this.value = StringValue.from(value);
}

static char[] from(char[] value) {
    return Arrays.copyOf(value, value.length);
} 
于 2013-09-12T13:37:35.303 に答える