BLOG

【プログラマー研修 Java】きゃのんの記録4

こんにちは! 「きゃのんです。

 

発売しましたねー、「ぶつ森」。皆さんもやってるでしょうか?

SNSなどでは、今作の略称は「あつ森」とされているようですが、

僕は「ぶつ森」と呼んでいきたいです。

 

「エフエフ派?」「ファイファン派?」みたいな派閥争いがしたいわけじゃなくて、

「熱盛」って言葉はもうあるじゃないですかー、野球界隈とかつけ麺界隈とかで。

「あつ森」って言われるとそっちが一瞬浮かんでしまうのです…。

 

「熱盛」といえば!

当然みなさんもチェック済みかとは思いますが、22日の西武ライオンズの「外崎選手」は攻守ともに素晴らしかった!

文句無しの「熱盛」でしたね!

昨シーズンは浅村選手、今シーズンは秋山選手という大きな大きな存在が去ってしまいましたが、

それでも強い!ライオンズ!

今年もリーグ優勝で3連覇+今年こそCS制覇を果たしてくれる事でしょう!

 

さぁ、みんなで西武ライオンズを応援しよう!

 

◆”null”? 空白? 例外?

public class Q1 {

	public static void main(String[] args) {
		String str = null;
		System.out.println(str + "null");
	}
}

さて、このコードをコンパイル、実行した場合、の結果はどうなるでしょうか?

①nullと表示される
②nullnullと表示される
③5行目でコンパイルエラー
④5行目で実行時エラー
(NullPointerException)

正解は… 

 

 

 

 

②です!

中身がnullの参照型の変数をpritlnで出力すると、”null”という文字列が返ってくるんですねー。

 

…あれ?おかしくない?

nullの変数を参照してるじゃん? NullPointerExceptionってnullの変数を参照してると出るじゃん?

ってことは④じゃない??

 

と思った方!するどい!

確かにそうなりそう!でも、実際に実行してみるとそうならない!

それは、printlnの方に秘密があるからなんです!

 

◆printlnって何をどう処理してるんだろう?

研修中は、Javaの統合開発環境は Eclipse を使用しています。

その機能の一つに、「Ctrl」キー を押しながら 「メソッド名をクリック」することで、

そのメソッドを宣言している箇所にジャンプできるというものがあります。

この機能を使って、pritln()がどう宣言されているかを確認し、どんな処理をしているのかを見ていきましょう!

 

    public void println(String x) {
        synchronized (this) {
            print(x);
            newLine();
        }
    }

synchronized(this){}は、他の処理が割り込んできて、処理結果が変わってしまうのを避けるというものです。
直接的に出力される内容に関わるものではないので、ここでは無視してしまいましょう。

残りの部分は簡単ですね!
print(x); で x を出力し、 newLine(); で改行しているだけなんです。
では、次に print(x); このメソッドを詳しく見てみましょう!

 

    public void print(String s) {
        write(String.valueOf(s));
    }

write(String型の引数)という部分が、コンソールに文字列を表示させているメソッドなんですね。

ところで、このメソッドに違和感はありませんか?
print(String s) の引数は、当然String型です。
なのに、write(String.valueOf(s))で、String型のsを、もう一度Stringにキャストしていますよね…?
どうも、このvalueOfには、String型に変換する以外にも、役割を持ってそうです。

では、これで最後! valueOf(s)  このメソッドを詳しく見てみましょう!

 

    public static String valueOf(Object obj) {
        return (obj == null) ? "null" : obj.toString();
    }

 

はい、来ました!ゴールに到達です!

return (obj == null) ? “null” : obj.toString();

これがゴールです!

valueOf(Object obj) の引数がnullかどうかを検査しているんです!

nullなら、”null”を返し、それ以外なら、toString()でString型にキャストして返しています

 

これが、問題のコードが例外にならず、”null”を返してくる理由なんですね!

 

◆感想

というわけで、String型の変数がnullの時、”null”を返してくる理由でした。

printlnメソッドの奥底に、ちゃんと理由があったんですね!

 

実はこの問題、先輩から出してもらったんです。

そして、正解はしたものの、その後の問題、「じゃあなぜ例外にならないか?」に答えられなかったんです。

 

“null”が返ってくることは知ってたけど、なぜそれが返ってくるかを理解していなかった。

 

なんでだろう?と常に疑問を持って、ちゃんと調べて解消していく。

これが自分に欠けていたなー。としみじみ感じて、反省した瞬間でした!

 

お、なんか教訓めいた、いい話っぽい記事になったぞ。

BLOGトップへ戻る