@ITの
文字列をequalsで判定する時
で行われた議論に対する私なりの考察をまとめておきます。
わかりやすいテーマだが結論しにくい
strの値が"hoge"か判定する際に
A: str.equals("hoge");
B: "hoge".equals(str);
のどちらで書くか。そしてその理由は?
このテーマは、非常に理解がしやすく、議論に参加するのは容易です。
Javaについて幾らかの経験があれば参加できるぐらいに必要とされる前提知識は少ない。
しかし、安易にどちらがよい、と白黒をつけることはできず、前提の置き方によって際どい判断が必要とされる、
「議論の技術」が要される話題です。頭の体操にはよいかもしれませんね。
議論する内容
このテーマの議論は多岐に渡りますので、先にロードマップを示しておきます。
- "hoge".equals(str)の構文的な分析
- "hoge".equals(str)は読みにくいのか?
- "hoge".equals(str)は読みやすいのか?
- NullPointerExceptionへの対応
- ヒューマンエラーのリスクの推定
"hoge".equals(str)の構文的な分析
Javaはオブジェクト指向を前提とした言語ですが、純粋なオブジェクト指向ではありません。
Javaではjava.lang.Objectの継承クラスとして扱われる「オブジェクト」と、
int値などの「プリミティブ型」とに大別されます。
プログラム用語で「リテラル」といった場合、「定数」を意味します。
代入ができ値が変化する「変数」に対して、固定の値を指して「定数」と言いますね。
Javaのプリミティブ型はオブジェクトではありませんから、メソッドの呼び出しはできません。
int i = 0; // 変数iはプリミティブ型
i.toString(); // コンパイルエラーとなる
上記例では変数iはint型ですね。プリミティブ型の場合、メソッド呼出しはできません。
ですから、i.toString()がコンパイルエラーになります。これはJavaの基礎の部分で学ぶ事項ですね。
数値の定数も当然ながらプリミティブ型ですから
0.toString(); // コンパイルエラーとなる
このケースでもコンパイルエラーになります。これは、Javaが完全なオブジェクト指向ではないことの現れです。
さて、オブジェクト型の場合、通常はnew演算子で生成しますから、「定数」とはなりません。
Object o = new Object(); // 右辺は定数ではない
ですが、String型の場合は特殊で、オブジェクト型なのに定数となりえます。
String str = "hoge"; // 右辺は定数
そしてオブジェクト型である以上はメソッド呼出しができるので
String str = "hoge"; // 右辺は定数
str.toString(); // コンパイルできる
"hoge".toString(); // コンパイルできる
というように、定数"hoge"に対してもメソッド呼出しができます。
"hoge".equals(str)は読みにくいのか?
次のエントリでは"hoge".equals(str)が読みにくいという意見に対して検討してみたいと思います。
投稿日時 : 2008年2月16日 19:06