📚

JavaにおいてNullと0は全く違うという業務仕様に当たったとき

に公開

システムにおいて、値を空欄で入れたとしても、それを0として扱ってはいけないときがあります。

今回はJavaにおいてそのような場面に遭遇した場合になぜそのような扱ってはいけない場面が存在するのかについて説明します。

よく値を空欄としたときに0としてはいけない場面としては計算処理が関わる場面です。

平均の値を算出したいといったときにnullの値が0に勝手に置き換わってしまうと、
0自体も数字としてカウントしてしまいます。
そのため、カウントする母数自体が実際より大きくなってしまい、平均の値が小さく算出されてしまいます。

int totalScore = 0;

for (Integer score : scores) {
    if (score != null) {
        totalScore += score;
    }
}

この時解決方法としては、初期値を0ではなく、nullに変更することです。

Integer totalScore = null;

for (Integer score : scores) {
    if (score != null) {
        totalScore = (totalScore == null) ? score : (totalScore + score);
    }
}

この修正点について、0からnull以外にも型がintからIntegerに変更となったことに気づかれるかと思います。

このように修正した理由としてはnullを当てはめたい時はintではなく、Integerでないといけないからです。
この点について解説します。

intについてはプリミティブ型であり、値そのものを指します。
対してIntegerはクラス(オブジェクト)を指します。

nullというのはオブジェクトが存在していないということを示すものです。
intにnullを当てはめた場合、数値そのものに「存在しない」という概念を当てはめようとすることになります。そのため、コンパイルエラーとなります。
対してIntegerはクラス(オブジェクト)であり、値を入れるための箱を持っているような状態です。
Integerにnullを当てはめた場合、Integerの箱に「存在しない」というnullの概念が入ることになります。
そのため、Integerではコンパイルエラーとならないのです。

Discussion