char から String への型変換
2009-11-03 追記:
グーグルから飛んでこられる方が多いので、結論を追記。
char --> String への変換方法
char c = 'a'; String.valueOf(c);
char[] --> String への変換方法
char[] cs = new char[10]; cs[0] = 'a'; cs[1] = 'b'; String.valueOf(cs);
以下、当時の検証内容。結論だけ知りたい方は読む必要なしです。
-
- -
何気に本日書いた
char[] c = new c[1]; c[0] = ...; ... String s = new String(c); ....
というような処理。
が、帰宅途中に気になってきたのが上記の部分。要するに char 配列を引数に String を生成したのだ。これ、
String.valueOf(c[0]);
と書くこともできる。どっちがいいの?まさか、String.valueOf を使うとすごい最適化してくれたりしないよね(もう new String で書いちゃったし!)というのが気になった。
valueOf() の方は、
public static String valueOf(char c) { char data[] = {c}; return new String(0, 1, data); } // new String() は・・・ // Package private constructor which shares value array for speed. String(int offset, int count, char value[]) { this.value = value; this.offset = offset; this.count = count; }
要するに、valueOf(char c) は参照渡しではなくて、値渡しなんで、そのままそれを内部配列として使用して String インスタンスにしているのね。
一方、new String(c); の方は・・・・
public String(char value[]) { int size = value.length; this.offset = 0; this.count = size; this.value = Arrays.copyOf(value, size); }
なるほど。こっちは char 配列で、参照渡しなので、配列のコピーを行う。Arrays.copyOf() の実装は、、、
public static char[] copyOf(char[] original, int newLength) { char[] copy = new char[newLength]; System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy; }
となっている。最終的には System.arraycopy() でコピーしているわけだ。
ということで、残念ながら私の実装は外れの方だったようだ。明らかに valueOf() の方がいいだろう。別に大きな差が出るとは思わないが、ループの中で 100 万回呼ばれる可能性もある処理だし、わかってて外れを書くのも気分がよくない。直すことにしよう・・・。
教訓としては、こういう生成系の処理において、イミュータブルなオブジェクトかプリミティブ型の引数が存在する場合は、そっちを使うようにしたほうがいいということ。逆に言えば、生成系処理を書く場合、その引数がイミュータブルかどうかは意識して処理を変えた方がいいということ。・・・お、今俺あたりまえのこといいましたヨー。
追記:
なんかもうこの処理全体的に気に入らなくなってきた。全部書き直すことに決めた。