- PR -

String#equals()を明示的に使うべきか?

投票結果総投票数:55
必ず使うべき 52 94.55%
使うべき 0 0.00%
使ったほうがいい 0 0.00%
場合による 1 1.82%
どちらでもいい 0 0.00%
使わなくていい 0 0.00%
使わないほうがいい 0 0.00%
  • 投票は恣意的に行われます。統計的な調査と異なり、投票データの正確性や標本の代表性は保証されません。
  • 投票結果の正当性や公平性について、@ITは一切保証も関与もいたしません。
投稿者投稿内容
あぶぽん
大ベテラン
会議室デビュー日: 2005/10/20
投稿数: 205
投稿日時: 2007-04-05 15:15
あぶです。よろしくお願いいたします。

コードレビューをしていて、ふと気づいたことが。。。

コード:
void execute(String state)
{
    if (state == Sample1.SWITCH_01_ON) {
        // ...
    } else {
        // ...
    }
}


  ああ、スイッチのオン/オフで切り替えるのね。。。って、
  stateはString!? ってことは、Sample1.SWITCH_01_ONもString?
  
  文字列の比較はString#equals()を使えっていつも言ってるじゃん。。。
  
  あれ!? テストケース通ってるよ!!

今、僕の信念は少し揺らいでいます。。。

* JDK1.4での話です。Java5ならenumuを使うべきという意見もあるかと思います。
* また、定数に文字列使うなよ! という意見はもっともですが、
* 今回は特に定数に限定しませんので、幅広く意見をいただけますでしょうか。
すみょし
常連さん
会議室デビュー日: 2007/01/25
投稿数: 36
投稿日時: 2007-04-05 15:19
Stringであることを明示的にするために、「必ず使うべき」に一票です。
(Objectとなるもの全ての比較はequalsを使うべきと思います)

[ メッセージ編集済み 編集者: すみょし 編集日時 2007-04-05 15:20 ]
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2007-04-05 15:33
本当に必ずか、といわれると違うのですが嘘も方便として必ずに1票。

例外ケースとしてはString.intern()が確実に施されている状況ですね。
パフォーマンスチューニング上の必要があってやるのであればよいのですが、
素人が使うと火傷を負う代物のひとつかもしれません。

また、コンパイル時点での文字列リテラルは同一インスタンスであることが
多いですから(言語仕様上mayなのかmustなのか調べていませんが…)
コード:
    System.out.println("hoge" == "hoge");


はtrueを返したりします。
しかし、下記の例では
コード:
    System.out.println("hoge" == new String("hoge"));


falseだったりするんですね。
テストケース側を修正してStringをnewしておくとよいかもしれません。
また、こういったコードはFindBugsを用いると効率よく探すことが出来ますね。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2007-04-05 15:41
分かってて使うなら==で比較もいいのですが、
原理がよく分かっていない方が書くことも考えると、
String#equalsの利用を必須とする規約は必要でしょうね。

そもそも==とequalsでは全く意味が違うのですが・・・
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2007-04-05 15:47
「必ず使うべき」 に投票しました。
私のグループのコーディング規約もそうしています。

ただし、C# 版では 「Equals メソッドは使ってはいけない」 にしています。
≒ C# からの移行組には注意してください!

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
小僧
ぬし
会議室デビュー日: 2002/08/14
投稿数: 526
投稿日時: 2007-04-05 15:48
文字列を文字列として比較したいのだったら、当たり前でしょ!というのに一票。

今手がけているプロジェクトでは、CやVBは経験あるけどJavaはお初
という方が多いんですけど、半数の方から文字列比較が出来ないという
相談を受けています。思わず == で比較してしまうというのも理解
出来なくは無いですし、そっちの方が分かりやすい気もします。
C言語だったら、ポインタ変数同士の比較と、strcmp関数で文字列同士を比較する
くらいの差なんですけどね。
これもfinal修飾子と同じで、動作するけど実行時エラーになる要因の
一つですよね。
あぶぽん
大ベテラン
会議室デビュー日: 2005/10/20
投稿数: 205
投稿日時: 2007-04-05 15:58
nagiseさん、じゃんぬねっとさん、皆さん、ありがとうございます。

Objectの内容比較には必ずequals()などの比較メソッドを使うべきだと
信じてきましたが、比較的大規模なプロジェクトで大々的に使われているので
正直、驚きました。

引用:

例外ケースとしてはString.intern()が確実に施されている状況ですね。
パフォーマンスチューニング上の必要があってやるのであればよいのですが、
素人が使うと火傷を負う代物のひとつかもしれません。


パフォーマンスに影響があるのは確かなのでしょうか?

レビューしたプロジェクトではそこまで考えられてるとは思えませんでした。
むしろ、見た目がキレイという理由っぽいですね。

定数を文字列にするのは、ログ運用上とのこと。トレードオフが難しい問題です。

引用:

また、コンパイル時点での文字列リテラルは同一インスタンスであることが
多いですから(言語仕様上mayなのかmustなのか調べていませんが…)



僕も最初はそれを疑い、状況を変えてテストしてみたりしました。


引用:

コード:
    System.out.println("hoge" == new String("hoge"));


falseだったりするんですね。
テストケース側を修正してStringをnewしておくとよいかもしれません。


まさにそうですね。

テスト駆動なので、初期からそうすべきでした。

これは、パターンとして提唱すべきですね。

>じゃんぬねっとさん
僕はC#については張りペタプログラマなのでよくわかりませんが、
なぜ、「Equalsメソッドは使ってはいけない」なのでしょうか?
あぶぽん
大ベテラン
会議室デビュー日: 2005/10/20
投稿数: 205
投稿日時: 2007-04-05 16:03
あれ!? 選択肢が化けてますね。。。
# 最初は化けてませんでしたよ〜。ねぇ?

一応、整理しておきます。

必ず使うべき
使うべき
使ったほうがいい
場合による
どちらでもいい
使わなくていい
使わないほうがいい
使うな
絶対に使うな

「使うな」、「絶対に使うな」の人は「使わないほうがいい」に投票して、
コメントで補足してください。

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