今日も色々と得ることがありました。
復習でハッとしたこともありましたけど、もちろん新しく学んだことも。
忘れないうちに今日も書いておこう。
到達不能コード(と、条件コンパイル)とSystem.out.println(obj)の話。
まずは到達不能コードについて。
[java] public class Main { public static void main(String[] args){ while(false){ System.out.println("ここにはたどり着けない"); } } } [/java]
こういうのが到達不能コード。
詳細はJava言語の仕様14.20にある。
このサイトとかいいかも。
http://www.y-adagio.com/public/standards/tr_javalang2/statements.doc.html
これによるとif(DEBUG){ x = 3;}はコンパイルエラーにならないそうな。
実際ならないし、これはassertを使うときに便利みたい。
というのも結城さんのJava言語で学ぶリファクタリング入門を読んでて、そこに載ってたから知ったってだけなんですけどね。
assert文を条件コンパイルすればクラスファイルが小さくなるらしい。
System.out.println(obj)の話。
これもリファクタリング学習中にあれ?と思ったことなんですけど。
事の発端は以下のコードから。
[java] public class Sample { public String toString(){ return "Sampleクラスです"; } } [/java]
[java] public class Main { public static void main(String[] args) { Sample sample = new Sample(); System.out.println("sampleを引数に取ると : " + sample); } } [/java]
これを実行すると結果はsampleを引数に取ると : Sampleクラスです
となる。
なぜこうなる・・・と15分くらい悩みましたけど、そう・・・printlnを見てみればいいんですよね。
ctrlを押しながらprintlnをクリックして宣言もとへジャンプ。
eclipseは便利ですな。
[java] public void println(Object obj) { String s = String.valueOf(obj); synchronized(this) { print(s); newLine(); } } [/java]
ふむ、なるほどvalueOfを呼んでるわけだ。
[java] public static String valueOf(Object obj) { return obj != null ? obj.toString() : "null"; } [/java]
なるほど、ここでtoStringを呼んでいる。だからか・・・!
toStringのオーバーライド前の挙動も見てみましたけど、それは説明だるいので省略。
C言語で同じように実装見てみようと思うと凄くだるそう。そもそも普通に理解できるように書かれているのだろうか。
後確かprintfとかってバイナリになってるから別にソースを用意しておく必要がありそうな・・。
まあ今度やってみよう。
追記(2010/08/03)
友人に間違いを指摘されたので追記。
println(obj)は中でtoStringやっててってのはあってるわけだけど、
System.out.println(“sampleを引数に取ると : ” + sample);
これはpublic void println(String s)が呼び出される。
けど+演算で結局は同じobj=>String変換が行われる。
というわけで半分あってました。
コメントを残す