- - PR -
文字列をequalsで判定する時
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2008-02-14 19:27
通常書くと、以下のようになります。 Stringのユーティリティ.isNullOrEmpty(str) 拡張メソッドがサポートされると、以下のように記述できます。 str.isNullOrEmpty(); ただ、拡張メソッドは通常の記述方法への置換えがサポートされるだけなので、 サポートされるようになってもNPEにはならないでしょう。 一応まだ組み込まれるか不明ですが、JDK7に入れる案が出ています。 http://weblogs.java.net/blog/forax/archive/2007/11/java_7_extensio.html なんか脱線してすみません・・・。 | ||||||||
|
投稿日時: 2008-02-14 20:02
アーしまった。
帰宅中の電車の中で考えをまとめていたら、 180度意見が変わってしまいました。 if(str != null && str.equals("hoge")){} としてしまったら、 結局if("hoge".equals(str)){}と等価なので、 僕が記述した理由1も2もなくなってしまいました。 | ||||||||
|
投稿日時: 2008-02-14 21:51
いえいえ。 議論の前提条件として、 ・strはnullを許容しない ・使う前にstrのnullチェックとエラー処理を行っている がありますので、strを使う箇所でのnullチェックは不要です。 なので、A派としては if(str != null && str.equals("hoge")){} とは書かないと。 前提条件で、 ・strはnullでも構わない となれば、当然書くことはありますが。 | ||||||||
|
投稿日時: 2008-02-15 07:42
明らかに期待している処理が異なりますよね。 if( str.equals( "hoge" ) ) と if( "hoge".equals( str ) ) を比較して考えるのは何かずれてると思います。 if( str != null && str.equals( "hoge" ) ) と if( "hoge".equals( str ) ) を比較して考えるのなら、両者は等価だと思います。 私は、前者が冗長なので、後者で記述して楽(サボり?)をしていますが、 一々IF文に str != null の条件を記述するのってうざくないですか? #感情論ですが。 _________________ 普通?常識?何ですかそりは。 日本語は難しい・・・。 | ||||||||
|
投稿日時: 2008-02-15 09:13
Null Objectパターンの代用みたいなものだと思えば、Bの多少の不自然さも許せると思えませんか?
NullPointerExceptionを投げちゃいけないだとか どこで投げなくちゃいけないとかはリファレンスや使用しているコーディング規約に従えばいいと思いますけど。 私はBをよく使いますよ。 ただしこんなイディオムをコーディング規約に入れるのはナンセンスだと思いますがね。 | ||||||||
|
投稿日時: 2008-02-16 19:29
この速さなら書けるかもしれないと思い、今までに思いついたことをメモ書きしておきます。
String#equals は、Object#equals をオーバーライドしています。 しかし、高いアプリケーションレイヤーでこのような低レベル(汎化された基底クラス)のメソッドを使うということが、マズいような気もします。本来は String クラスに、equalsIgnoreCase メソッドのような感じで equalsNotIgnoreCase メソッドがあっても良かったのではないかと思います。(なお equalsIgnoreCase メソッドは equals メソッドを意識して引数に null を許しますが、これについてはここでは触れないことにします。) 高いアプリケーションレイヤーで出てくるサニタイジングされていないデーターを扱うためにわざわざ Object#equals が引数 null を許しているわけではないだろうと思います。 Object#equals の javadoc を読むと、 http://java.sun.com/javase/ja/6/docs/ja/api/java/lang/Object.html#equals(java.lang.Object) 「対称性」について明記されています。 これを鑑みると、str.equals("hoge") でも "hoge".equals(str) でもどっちでも良いという考えも良いかもしれません。 str.equals("hoge") と書いてあった部分を、アプリケーションの仕様変更でちょっと手直しして、str.startsWith("hoge") などとしたいときに、もしも元が "hoge".equals(str) となっていると、手直しが面倒というかちょっとしっくりきません。(キーボードのタイプ量がどうこうという意味ではありません。) いわゆるユーティリティークラスを自前で作って、 static boolean equalsWithNull(String, String); のようなメソッドを作って null の取り決めを自分で決めるのが、社内等の狭い枠内での標準化という意味では良いのかもしれません。 しかし、人に見せるソースコードの場合、「このしょうもない equalsWithNull メソッドってなんだ?」のように読む人に一瞬、疑問を持たせてしまうというデメリットがあるでしょう。 コンピューターの動作として、実行時に(NullPointerException のような)エラーが起きた場合、即停止することが安全なのか、ごまかしながらも動き続けることが安全なのか、は永遠の課題だろうと思います。人の持つ価値観の問題でもあります。 思い出話になりますが、昔、インタープリター型の BASIC を使っていたとき、RUN させて "Syntax Error" が出ると嬉しかったものです。"Illegal Function Call" が出るのは嫌でした。 いまどき、コンパイラーなので実行時に "Syntax Error" が出ることはなくなりましたが、今の Java の NullPointerException が昔の BASIC の "Syntax Error" に相当するのかなと思っています。たぶん、このニュアンスが分かる方はものすごく少ないでしょうね。 ![]() | ||||||||
|
投稿日時: 2008-02-16 20:29
コード上ではstr.equals("hoge")であっても 実際はnull.equals("hoge")になるようなものですからね・・・。 そこのとこ理論と仕様とのかみ合わせが難しいんですよね。 対称性のある関数がメソッドになってるのが諸悪の根源で、 演算子==を呼び出せば静的メソッドが呼ばれるという風にすればこんな 問題は出てきませんでした。 | ||||||||
|
投稿日時: 2008-02-17 12:10
むしろ、str.equals(null)が例外を出すようにしていれば良かったのかも。
そうすれば対称性も保たれるし。 equals()の中でのnullチェックも不要になるから、速度も誤差程度には速くなるだろうし。 |