Java Tips | 基本ユーティリティ:Math.decrementExact()

Web APP Java
スポンサーリンク
スポンサーリンク

Math.decrementExact()とは何か

Javaで業務システムを開発していると、数値を1減らす処理を行う場面が頻繁にあります。

例えば、

  • 在庫数の減少
  • 残りチケット数の管理
  • 残タスク数の更新
  • 処理待ち件数の減少
  • 残ライセンス数の管理
  • カウンタのデクリメント

などです。

通常は、

value - 1
Java

や、

value--
Java

で十分に見えます。

しかしJavaには、

Math.decrementExact()
Java

という安全な減算を行うためのメソッドがあります。

このメソッドは単純に1を減らすだけではありません。

数値のアンダーフロー(下限超過)を検知し、例外を発生させる重要な役割を持っています。

まずはアンダーフローを理解しよう

Math.decrementExact()を理解するためには、まずアンダーフローを理解する必要があります。

int型には最小値があります。

-2147483648

これは、

Integer.MIN_VALUE
Java

です。

この値からさらに1を引いてみましょう。

// 最小値
int value =
        Integer.MIN_VALUE;

// 1減算
value--;

System.out.println(value);
Java

実行結果

2147483647

突然最大値になってしまいました。

これがアンダーフローです。

なぜアンダーフローが危険なのか

初心者のうちは遭遇しにくいかもしれません。

しかし業務システムでは、

  • 残在庫数
  • 残チケット数
  • 残ポイント数
  • 残ライセンス数
  • 残処理件数

などの管理で発生する可能性があります。

気付かないうちにマイナス方向へ行き過ぎると、本来ありえない巨大な正数になってしまう場合があります。

その結果、システム障害や不正な業務データの原因になります。

Math.decrementExact()の基本構文

構文は非常にシンプルです。

Math.decrementExact(値)
Java

例を見てみましょう。

// 値
int ticketCount = 10;

// 1減算
int result =
        Math.decrementExact(
                ticketCount
        );

// 結果表示
System.out.println(result);
Java

実行結果

9

1だけ安全に減算されています。

ステップバイステップで理解する

ステップ1:値を準備する

// 在庫数
int stock = 100;
Java

ステップ2:Math.decrementExact()を実行する

// 在庫を1減らす
int nextStock =
        Math.decrementExact(
                stock
        );
Java

ステップ3:結果を確認する

// 出力
System.out.println(nextStock);
Java

実行結果

99

安全に1減っています。

普通の減算との違い

通常の減算です。

// 通常減算
int result =
        value - 1;
Java

こちらはアンダーフローしても気付きません。

一方、

// 安全減算
int result =
        Math.decrementExact(
                value
        );
Java

はアンダーフローを検知します。

最重要:アンダーフロー時の動作

Math.decrementExact()最大の特徴です。

// 最小値
int value =
        Integer.MIN_VALUE;

// 減算
Math.decrementExact(value);
Java

実行結果

ArithmeticException

例外が発生します。

つまり、

「危険な状態になった」

ことをプログラムが検知できます。

通常減算との比較

通常減算

// アンダーフロー
int result =
        Integer.MIN_VALUE - 1;
Java

結果

2147483647

異常な値になります。

Math.decrementExact()


// アンダーフロー検知
Math.decrementExact(
        Integer.MIN_VALUE
);
Java

結果

ArithmeticException

即座に異常を発見できます。

例外処理と組み合わせる

実務では例外処理を行います。

try {

    int nextValue =
            Math.decrementExact(
                    currentValue
            );

} catch (ArithmeticException e) {

    System.out.println(
            "アンダーフローが発生しました"
    );

}
Java

これが基本パターンです。

long型にも対応している

Math.decrementExact()はlong型もサポートしています。

// long型
long count = 100L;

// 1減算
long result =
        Math.decrementExact(
                count
        );

System.out.println(result);
Java

実行結果

99

実務でよくある利用例① 在庫管理

// 在庫
int stock = 50;

// 出庫処理
stock =
        Math.decrementExact(
                stock
        );
Java

在庫管理システムで利用できます。

実務でよくある利用例② 残チケット管理

// 残席数
int ticketCount = 100;

// 予約受付
ticketCount =
        Math.decrementExact(
                ticketCount
        );
Java

イベント予約システムで利用できます。

実務でよくある利用例③ バッチ残件数管理

// 残件数
long remainCount = 1000;

// 処理完了
remainCount =
        Math.decrementExact(
                remainCount
        );
Java

バッチ処理システムで活用できます。

実務でよくある利用例④ ライセンス管理

// 利用可能ライセンス
int licenseCount = 5;

// 利用開始
licenseCount =
        Math.decrementExact(
                licenseCount
        );
Java

ライセンス管理システムで利用できます。

Math.incrementExact()との違い

よくセットで使用されるメソッドです。

Math.incrementExact()


// 1加算
Math.incrementExact(value);
Java

結果

value + 1

Math.decrementExact()


// 1減算
Math.decrementExact(value);
Java

結果

value - 1

どちらもオーバーフロー系の問題を検知してくれます。

Math.subtractExact()との違い

こちらもよく比較されます。

Math.decrementExact()


// 1だけ減算
Math.decrementExact(value);
Java

Math.subtractExact()


// 任意の値を減算
Math.subtractExact(
        value,
        100
);
Java

用途によって使い分けます。

内部でどのような処理をしているのか

イメージとしては次のような動作です。

// イメージコード
if (value ==
        Integer.MIN_VALUE) {

    throw new ArithmeticException();

}

return value - 1;
Java

実際の実装はより最適化されていますが、考え方はこのようなものです。

情報セキュリティの観点から見る重要性

Math.decrementExact()はセキュリティ機能ではありません。

しかしシステムの信頼性を高める重要な役割を持っています。

アンダーフローを放置すると、

  • 在庫数異常
  • ライセンス数異常
  • チケット数異常
  • 採番ロジック異常
  • 統計データ破損

などにつながる可能性があります。

特に大規模業務システムでは、アンダーフロー検知は重要な品質対策のひとつです。

実務で使えるテンプレート集

基本テンプレート


// 安全な1減算
value =
        Math.decrementExact(
                value
        );
Java

在庫管理テンプレート


// 出庫処理
stock =
        Math.decrementExact(
                stock
        );
Java

例外処理付きテンプレート

try {

    value =
            Math.decrementExact(
                    value
            );

} catch (
        ArithmeticException e
) {

    // エラー処理

}
Java

long型テンプレート


// long型減算
count =
        Math.decrementExact(
                count
        );
Java

初心者が覚えておくべき重要ポイント

  • 1を安全に減算するメソッドである
  • アンダーフローを検知できる
  • 異常時はArithmeticExceptionが発生する
  • int型とlong型に対応している
  • 在庫管理で便利である
  • 通常の「-1」より安全である
  • 大規模システムで特に有効である

まとめ

Math.decrementExact()は、安全に1を減算するためのJava標準メソッドです。

  • 値を1減少できる
  • アンダーフローを検知できる
  • 異常時にはArithmeticExceptionが発生する
  • int型・long型の両方に対応している
  • 在庫管理や残数管理で活躍する
  • システムの信頼性向上につながる
  • Java開発者が知っておきたい安全な演算ユーティリティである

特に業務システムでは、残数管理や在庫管理など「減算」が非常に多く登場します。Math.decrementExact()を利用することで、単なる「-1」では見逃してしまうアンダーフローを確実に検知できるようになります。Math.incrementExact()とあわせて理解することで、より安全で堅牢なJavaアプリケーションを開発できるようになるでしょう。

タイトルとURLをコピーしました