インスタンスをprintするとなぜ文字列が出てくるの!

今日も色々と得ることがありました。

復習でハッとしたこともありましたけど、もちろん新しく学んだことも。

忘れないうちに今日も書いておこう。

到達不能コード(と、条件コンパイル)と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変換が行われる。

というわけで半分あってました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です