2012-10-16 4 views
6

次はのStringクラス'originalValue.length> size'はStringコンストラクタでどのように起こりますか?

public String(String original) { 
int size = original.count; 
char[] originalValue = original.value; 
char[] v; 
if (originalValue.length > size) { 
    // The array representing the String is bigger than the new 
    // String itself. Perhaps this constructor is being called 
    // in order to trim the baggage, so make a copy of the array. 
     int off = original.offset; 
     v = Arrays.copyOfRange(originalValue, off, off+size); 
} else { 
    // The array representing the String is the same 
    // size as the String, so no point in making a copy. 
    v = originalValue; 
} 
this.offset = 0; 
this.count = size; 
this.value = v; 
} 

のコンストラクタです。しかし、私は

if (originalValue.length > size) 

が起こる可能性がどのようだろうか?コメントは、手荷物をくすぐる、何ですか手荷物を参照してください?

+3

このStringクラスの他のコンストラクタとメソッドを見てください。実際のコンテンツに必要なものよりも、配列内に割り当てられた領域が大きい文字列を作成する方法はありますか? –

答えて

4

部分文字列を見てみましょう。これがどのように起こるかがわかります。

たとえば、String s1 = "Abcd"; String s2 = s1.substring(3)とします。ここでs1.size()は1ですが、s1.value.lengthは4です。これはs1.valueがs2.valueと同じであるためです。これはパフォーマンス上の理由から行われます(元のStringの内容をコピーする必要がないため、部分文字列はO(1)で実行されています)。

部分文字列を使用すると、メモリリークが発生する可能性があります。あなたは本当に長いStringを持っており、あなたはそれの小さな部分を保持したいだけです。部分文字列を使用するだけで、実際には元の文字列の内容がメモリに保持されます。 String snippet = new String(reallyLongString.substring(x,y))を実行すると、不要になった大きな文字配列のメモリを浪費することがなくなります。

さらに詳しい説明はWhat is the purpose of the expression "new String(...)" in Java?も参照してください。

+1

'String s1 =" abcd "にあります。文字列s2 = s1.substring(3) '、s1、s2は実際には同じ値配列' {'a'、 'b'、 'c'、 'd'} 'を保持します。それらの違いは** offset **と** count **です。 String(String.substring(...))メソッドは、大きな文字列の部分文字列を取得しようとするとメモリリークを回避できます。ありがとう〜 – sun