結論
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テストで限界値テストを組んであれば気付けた。
他にも、色々やりようはあるような気はしますが。
最後に
この件が起きるまでキャッシュの存在を知らなかったので良い気づきとなった。