まず、String#valueOf(long l)
APIの 説明文には、「Long#toString(long l)と同じ※1」って書いてあるようにみえるけど、その下にあるソースコードは、実際には Long#toString(long i, int radix) を呼び出していた。
で、その中身をみてみる。
結局その先でLong#toString(long l)を呼び出していたので、※1の説明文は間違っていないことがわかった。
ということで、「プリミティブなlongの文字列表現を得る際に、StringおよびLongクラスのどちらのStaticメソッドを使うか?」は、結果的にどっちでも同じ。という結論。
ま、ここまでは、わざわざソースを確認しなくても、Java APIを読めばわかるし、冒頭のツイートも、そんなことを問題にしているわけでは無い。
で、Javaの設計思想的なことを考えてみた。
まず、Long。Longの存在意義は、プリミティブlongのお世話をするってのもあると思う。(←個人的主観です)
そうすると、LongにStaticメソッドとしてtoString(long l)を実装したのは理解できる。
そして、String。元来、Stringは文字列をイミュータブルに持つオブジェクトの役割を与えられていると思う。(←個人的主観です)一方で、便利に使えるように、オブジェクトではなく、クラスのStaticメソッドとしていろんなvalueOfメソッドが実装されている。
そうすると、以下のような書き方が出来てしまうことになる。
System.out.println("あ".valueOf(100l));
注:(”インスタンスがあるのにStatic呼び出しは推奨されない”って警告が出るから気付くことはできるけど、実行は出来てしまうので、新人プログラマなどが開発メンバーにいると、紛れ込むかもしれない。)
ただし、いくら便利とはいえ、String#valueOf(someType)なオーバーロードはちょっと自重したほうがいいんじゃないかな?というのが私の意見。
なぜか?
以下のコーディングがあります。文法的には問題ありません。
String a = String.valueOf(hogelong);
System.out.println(a);
String b = Long.toString(hogelong);
System.out.println(b);
でも、hogelongの宣言がものすごく遠くにあって、しかもこんな宣言だとしたら・・・どうなるでしょう。
char[] hogelong = null;
まず、String#valueOfを使った場合・・・
long型のようにみえたhogelongは実は、char型だったけど、オーバーロードの弊害で、コンパイルは通ってしまいます。そうすると実行するまでエラーに気付くことができません。
次に、Long#toStringを使った場合・・・
今度は、コンパイルの段階でエラーになってくれました。
どうやら安全性の観点では、Long#toStringに軍配があがりそうです。
以上
0 件のコメント:
コメントを投稿