あんにんにっき。

日々思ったことや、おこったことを記録するブログ。要するに日記。

java と文字オブジェクト

 "文字列".equals("文字列") と、 "文字列" == "文字列" は比較してるけど意味が違う。
 javaを覚えたての頃、==でなく、equalsで比較しないとダメ、と言われて特に考えずにequalsで比較していた。けれども、理由は知らなかったし、あまり深く考えたこともなかった。
 というわけで唐突に考えてみた。
 javaの場合

"a" + "b" == "ab"

 である。
 というのも、文字列は、同じインスタンスを共有するから。
 "a" + "b" でできる"ab"と、 "ab"は同じインスタンスである。だから == が成立する。


 でも、

"ab ".trim() != "ab"

 である。
 "ab ".trim()の結果の"ab"と"ab"は異なるインスタンスである、という事になる。trimでなく、substringの場合も同様だった。

 という事はこんな感じか。

  1. trimやsubstringで操作した際、新しい文字列のインスタンスは生成されない。
  2. 「+」で結合して作った場合、同一の文字列がある場合、同じインスタンスを指す。

 なるほど、文字列インスタンスは、同じインスタンスを共有するものだ、と認識していたのだが、誤認だったようだ。
 ならば、equalsで比較しないとだめ、という理由も分かる。同じ内容の文字列かどうかで比較したいときに使うのはequalsだから。



 調べてみたら、文字列リテラルの場合に、同じインスタンスを参照する事になるようだ(内部で、String.internを使うようだ)。だから、リテラルで無い場合(trimとかしたとき)は、違うインスタンスを指す。
 「+」でリテラルリテラルを結合した場合も、リテラルとして扱われるようだ。


 いまさらだけれども、ちょっとだけ賢くなった。
 以上、知っている人にとってはあたりまえすぎるであろう話、でした。