kagamihogeの日記

kagamihogeの日記です。

java.lang.String探訪

最近あんまりコード書く気力が沸いてこない。なので、じゃあ何か読んでみるか、ということでjava.lang.Stringを選択。普段何気なく使ってるしね。

分量自体はやたらめったら多いわけでない。コード中になんで?と思う個所もあれば、なるほどと思う個所もあった。その中からちょっと面白かった点をいくつかメモ。

無駄な知識

lastIndexOfは、捜索対象の文字列が見つからないと-1を返す。が、空文字("")を入れたときは捜索開始位置に関わらず、元の文字列の長さを返す。


//J2SDK1.4.2_09より抜粋
//lastIndexOfの最初の方を抜粋
int rightIndex = sourceCount - targetCount;
if (fromIndex > rightIndex) {
fromIndex = rightIndex;
}
/* Empty string always matches. */
if (targetCount == 0) {
return fromIndex;
}

とはいえ「空文字が最後に現れた位置」なんぞ意味が無い行為なのでホントーに無駄な知識。

Stringのプロパティ

Stringには文字列を保持するcharのほかに、offsetとcountというintのインスタンス変数がある。charで保持している文字列のうち、実際に使用する部分はここからここまでを示す、を持っている・・・らしい。

Stringはimmutableオブジェクトなわけで。Stringのコードを上から下までみても、コンストラクタでoffsetに0、countにchar[]のlengthを入れたあと値を変更するインタフェースはない。コレのおかげでちょっと読みにくい部分があるんだが、これの存在意義がわからん。

古いJDKのときは、immutableじゃなかったのかなぁ?

コピーコンストラクタ

これも使う機会がまずないので、無駄といえば無駄な知識。Stringを引数にとるコンストラクタについて。

JavaのStringというか参照型の説明してるとこで、下みたいなコード例はちょくちょく見かけます。


String hoge1 = "hoge";
String hoge2 = "hoge";
String new_hoge = new String(hoge2);
if (hoge1 == hoge2) {
System.out.println("こっちは通らない");
}
if (new_hoge == hoge2) {
System.out.println("こっちは通る");
}

Javaは同一文字列であれば同一参照を用いる、てヤツの説明でよく出てくる例。じゃあそのコンストラクタの中身はというと・・・


//J2SDK1.4.2_09より抜粋
public String(String original) {
this.count = original.count;
if (original.value.length > this.count) {
// originaiのcharが新しいオブジェクトのcharより大きくなる場合、
// char両端のゴミをトリムした文字列をコピーします。
this.value = new char[this.count];
System.arraycopy(original.value, original.offset,
this.value, 0, this.count);
} else {
// originaiと新しいオブジェクトのchar
長が等しい場合はコピーする
// 意味がありません。
this.value = original.value;
}
}
//コメントの日本語訳は余り気にしないでくれ

countがchar長より大きい場合、実際に使ってる部分だけをコピーする・・・らしい。前述の理由によりこっちのifは通らない気がするんだが・・・。

elseの方を見ると、Stringオブジェクトそのものは別になるが内部で保持するcharは同一の参照を使うことが解かります。なるほど。まぁ使う機会が無いのには変わりないけどさ。

ちなみに、ここにEffective JavaにStringクラスのコピーコンストラクタは使わないほうがいい、と書いてあるのでちょっと見てみた。

(Effective Java p.64 第二段落より抜粋)
実際、コピーは元のインスタンスと永久に同値ですので、コピーを行う必要は決してありません。したがって、不変クラスに対して、cloneメソッドやコピーコンストラクタを提供する必要がありませんし、提供すべきではありません。

おっしゃる通りでございますな。