最近、ランダムなアドホック テストでコードに異常なバグを発見しました。というわけで、テストケースを作りました。
これが私のテストケースです:
SampleRequest request = new SampleRequest();
request.setA(null);
request.setB(null);
assertEquals(null, request.getAOrB());
A と B は java.lang.Integer 型として定義されており、それらの値をリクエストに設定するためのダイレクト セッター メソッドがあります。
列挙も含まれます。プリミティブ整数値と、このコードで使用されるメソッドがあります。関連する部分をここに投稿します。
enum Swapper {
public int c;
Swapper findSwapperToUse(final int a) {
for(Swapper swapper : values()) {
if(swapper.c == a) {
return swapper;
}
}
return null;
}
}
さて、これが混乱している方法です。そのメソッドでテスト メソッドを呼び出すと、NPE が発生しますが、メソッドの最後の行で発生します。
public class SampleRequest {
private Integer A;
private Integer B;
public void setA(final Integer A) {
this.A = A;
}
public void setB(final Integer B) {
this.B = B;
}
public Integer getAOrB() {
return A != null ? Swapper.findSwapperToUse(A).c
: B;
}
}
テストでは、A と B の両方が null に設定されます。したがって、A != null は false を返します。しかし、 : B 行の行番号で NullPointerException が発生します。
私の推測では、何らかの理由で最初の式 Swapper.findSwapperToUse(A).c が評価されているため、オートボクシングによって A.intValue() が呼び出され、null 値で NullPointerException が発生したと考えられます。デバッグを通じて、findSwapperToUse() が呼び出されていないことがわかっています。
ただし、この質問によると、これは発生しないはずです: Java 3 項 (即時の場合) 評価
選択されていないオペランド式は、条件式の特定の評価では評価されません。
null (B) を返しても NullPointerException は発生しません。ここで null の結果を返してもまったく問題ありません。
一体何が起こっているのですか?
編集:私はこれを避けるためにコードを変更したことを追加するのを忘れていました.ifステートメントをまっすぐに使用してください.
public Integer getAOrB() {
if(A != null) {
return Swapper.findSwapperToUse(A).c;
}
return B;
}