- PR -

文字列をequalsで判定する時

投稿者投稿内容
kuma
大ベテラン
会議室デビュー日: 2004/02/25
投稿数: 110
投稿日時: 2008-02-09 12:31
引用:

unibonさんの書き込み (2008-02-08 12:50) より:

A は testStr が null だった場合、NullPointerException になってくれるという"利点"があります。これは欠点ではなく"利点"だと私は考えます。


私はこれに利点は感じられませんね
nullを許さないのであれば初めに判定をしてメソッドにあったExceptionをだすべきです。
NullPointerExceptionでは利用する側に不親切すぎます。

引用:

@testStr != null && testStr.equals("test")
A"test".equals(testStr)


これは確かに状況によるかもしれませんが、比較条件が1つのみならば
A"test".equals(testStr)
を使いますね
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2008-02-09 12:42
引用:

未記入さんの書き込み (2008-02-09 11:37) より:
null を期待していないのなら、それが分かるように書くべきでしょう。たしかに A の書き方にはアサーション効果がありますが、アサーションを期待して書かれたものかどうかを読み取ることはできません。このような明示されないアサーション効果は、細かいロジックを見たいときには、逆に、思考の妨げになると思います。


アサーションについてですが、
コード:
if (testStr == null) {
    throw new なんちゃらRuntimeException();
}
if (testStr.equals("test")) {
    ...
}


と書いても良いとは思いますし、assert を使っても同じことだと思います。
しかし、これは、
コード:
if (testStr.equals("test")) {
    ...
}


と等価でしょう。

逆に、"test".equals(testStr) で同じことをしようとすると、
コード:
if (!(testStr == null || testStr != null)) {
    throw new なんちゃらRuntimeException();
}
if ("test".equals(testStr)) {
    ...
}


となりますが、これも、
コード:
if ("test".equals(testStr)) {
    ...
}


と等価です。(あたりまえですが、常に !(testStr == null || testStr != null) == false なので。)
わたなべ
大ベテラン
会議室デビュー日: 2007/12/09
投稿数: 123
お住まい・勤務地: 札幌
投稿日時: 2008-02-09 12:50
結論は出ないという前提で。

自分は
if(str.equals("hogehoge"))
でなければ気持ち悪いです。
主語と動詞の関係があるわけですから、「strが"hogehoge"と同じか?」という意味と、「"hoghoge"がstrと同じか?」ではニュアンスが違いますからね。

NullPoに関してもしいて言えば利点かな、と思います。
フレームワークなどでstrがnullでない前提でのチェックであれば、NullPoは発生するべきでしょう(多分、別の箇所で設定をミスしているなど)。

状況に応じて使い分けるべきかとは思いますが、それなりのスキルを持っているPG相手ならばstr.equalsの方式で統一しても問題ないと感じます。
だけど、大きいプロジェクトで初心者を大量に導入しなければならないって状況だと、定数を前に統一して保身を計ります(笑)
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2008-02-09 12:51
引用:

kumaさんの書き込み (2008-02-09 12:31) より:
引用:

unibonさんの書き込み (2008-02-08 12:50) より:

A は testStr が null だった場合、NullPointerException になってくれるという"利点"があります。これは欠点ではなく"利点"だと私は考えます。


私はこれに利点は感じられませんね
nullを許さないのであれば初めに判定をしてメソッドにあったExceptionをだすべきです。
NullPointerExceptionでは利用する側に不親切すぎます。


Java のプログラムで、自分で書いた仕様書(JavaDoc)に書いていない RuntimeException(やその派生クラスの NullPointerException) を throw するのは、バグありの不十分なプログラムです。
実行時に NullPointerException が出るかもしれない(という想定がある)のならば、当然、判定は必要です。
私が書いた「NullPointerException になってくれる」というのは、そのような必要な判定はしたある上での、実行時に想定外な状況に陥った場合の話です。
わたなべ
大ベテラン
会議室デビュー日: 2007/12/09
投稿数: 123
お住まい・勤務地: 札幌
投稿日時: 2008-02-09 12:57
追記ですが、これは不等号や比較子をどう記述するかって話題とも関連しますね。
"test".equals(testStr) が気持ち悪い自分は、当然のごとく
if(100 == num)
if(10 > value)
のような書き方は気持ち悪くてダメです・・。

どうして、if(10 < value)だけは変数を右に記述するんだ!って言われるわけですが(笑)
OTAKE
会議室デビュー日: 2008/02/08
投稿数: 18
投稿日時: 2008-02-09 13:02
引用:
nullを許さないのであれば初めに判定をしてメソッドにあったExceptionをだすべきです。


その通りです。
ただし、nullかどうかを判断するのは利用時ではなく、生成時(入力時)です。
入り口でnullかどうかを判断しておけば、利用時に毎回nullチェックをする必要がなくなります。
nullでないことが分かっているので、str.equals()と書けるわけです。

str !=null && str.equals("hoge") と "hoge".equals(str)は等価だとして、
str !=null && !str.equals("hoge") はどう書きますか?
!"hoge".equals(str) では駄目ですよね。
未記入
大ベテラン
会議室デビュー日: 2008/02/07
投稿数: 115
投稿日時: 2008-02-09 13:40
引用:

assert を使っても同じことだと思います。しかし、これは、if (testStr.equals("test")) { ... } と等価でしょう。


私はアサーションとしての効果があるとは言いましたが、assert とは発生する例外が異なりますので等価だとは考えていません。AssertionError は利用者(開発者)に事前条件が満たされていないことを伝えますが、NullPointerException では、その意図を十分に伝えることができません。kuma さんも言っているように NullPointerException では不親切なのです。

引用:

> 他人の書いたコードであっても?

ちゃんとしたプログラマーが書いたコードなら分かります。


おかしなことを言う人ですね。なぜ、他人の書いたコードの意図があなたに分かるのでしょう? 他人の書いたコードの意図をあなたが読み取れるのは「ちゃんとした」という条件を勝手に付けているからですよね。

世の中に、ちゃんとしたプログラマしかいないのであれば…

引用:

私は逆に "test".equals(testStr) というコードを見た場合「このコードは testStr が null のことを考慮して書かれているのだろうか?」と心配になります。たしかに equals メソッドは引数が null の場合と非 null の場合の両方を許しますが、両方のケースを網羅して動く条件判断をもくろんだコードなのかが、不安です。


こんな心配をしたり、不安を感じたりするはずないと思いますけど? ちゃんとしたプログラマしかいないのであれば、"test".equals(testStr) は testStr が null でも正しく動作するように考えられたコードということになります。

実際には、ちゃんとしたプログラマばかりではないので、私は null 対処の意図が伝わるように書きなさいと言っているのです。

それに対して、あなたは…

・A のコードは、ちゃんとしたプログラマが書いたものという前提なので、testStr が null を期待していないことは明らかだ。

・B のコードは、(ちゃんとしたプログラマが書いたものではないかもしれないから) 引数 testStr が null であった場合のことが考慮されているかどうか心配だ。

と言っているわけですね? ずいぶんと都合の良いご主張だこと。
kuma
大ベテラン
会議室デビュー日: 2004/02/25
投稿数: 110
投稿日時: 2008-02-09 17:17
引用:

未記入さんの書き込み (2008-02-09 13:02) より:

str !=null && str.equals("hoge") と "hoge".equals(str)は等価だとして、
str !=null && !str.equals("hoge") はどう書きますか?
!"hoge".equals(str) では駄目ですよね。



前半は多分思いは一緒なので割愛して後半のみ引用させてもらいます。

何を以って等価と言われているのか解りませんが
型の判定

値の判定
を無理に1つにしようとしていませんか?
コード:
if (testStr != null && testStr.equals("test")) {}



コード:
if (testStr != null) {
  if(testStr.equals("test")){
  }
} 


と等価であって
コード:
if ("test".equals(testStr)) {}


とは値の判定という意味で同じになるだけです。
型の判定までは行っていません。

スキルアップ/キャリアアップ(JOB@IT)