3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

株式会社オープンストリーム "小ネタ"Advent Calendar 2020

Day 23

【Java】Integerを==で比較した結果trueを返却していた問題

Last updated at Posted at 2020-12-23

結論

Integer(≠int)を比較する場合に**==を利用すると、-127~+128までの値はtrueを返却する組み合わせ**がある。

何が起きたか

Integerを**==**で比較していた個所が、ある時から突然falseを返却するようになった。
※テストで使った値では正常になってしまったため気付かなかったようだ。

以下の2つの要素の組み合わせで発生する

1.Integerへの値セット方法

主に以下の3通りがある。
Integer i1 = 16;
Integer i2 = Integer.valueOf(16);
Integer i3 = new Integer(16)

上記の1のパターンはオートアンボクシングされ、コンパイルされた結果は2と同様にvalueOfメソッドを利用した処理となる。(1と2は同値)
参考:【Java】オートボクシング、アンボクシング

2.Integerのキャッシュ仕様

Integer.valueOf()は、通常設定での仕様上-128~+127まではキャッシュ(つまに同じインスタンス)を返却する仕様となっている。
参考:Integerのソースを読んでみた

**==**での比較時にtrueを返却する組み合わせとは?

  • セットする時にInteger.valueOf()を利用している
  • セットする数値が-128~+127の範囲

本件が気付き辛いポイント

  • O/Rマッパーなどを利用しているとInteger型に値をどのようにセットしているか気にしない
  • シーケンス値など0から増えていく場合に128以上の値でテストしない可能性がある
  • 数値型はintが利用されている場合が多いと思う思い込み(==で比較すればいいという事になる)

本件と同じ問題とならないようにするには

Unitテストで限界値テストを組んであれば気付けた。
他にも、色々やりようはあるような気はしますが。

最後に

この件が起きるまでキャッシュの存在を知らなかったので良い気づきとなった。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?