Java 8では

Math`クラスに新しいメソッドが導入され、オーバーフローを処理するための

ArithmeticException`がスローされます。これらのメソッドは

addExact

、` substractExact`、

multiplyExact

、` incrementExact`、

decrementExact

、` negateExact`から

int`と

long`引数で構成されます。さらに、

long`値を

int`に変換する静的

toIntExact`メソッドもあります。これは

ArithmeticException`をスローします。

Java 8より前に、プログラマーは、オーバーフローするコード内の変数を見つけるために手動でデバッグする必要がありました。私は、Java 8が結果オーバーフロー時に例外をスローする新しい一連のメソッドを導入したことを知りました。多くの開発者にとって、この変更に大きな影響はありませんが、私自身のような謙虚な開発者にとっては、結果が間違っている理由を理解したり、オーバーフローを避けるために複雑な予防措置を取る必要があります。

1. Math.multiplyExact

この例は、一般的な乗算と新しい

multiplyExact

MultiplyExact.java

package com.techfou.exactmethods;

package com.techfou;

public class MultiplyExact {

    public static void main(String[]args) {

        int x = Integer.MAX__VALUE;//( = 2 147 483 647)
        int y = Integer.MAX__VALUE;
        Object z;

        System.out.println("---Before Java 8---");
        z = x **  y;
        System.out.println("z : " + z);

        System.out.println("\n---Since Java 8---");
        try {

            z = Math.multiplyExact(x, y);

        } catch (ArithmeticException e) {

            System.out.println(e.getMessage());//Java 8 throws integer overflow

            z = Math.multiplyExact((long) x, (long) y);
            System.out.println("z : " + z);
        }

        if (z instanceof Long) {
            System.out.println("\n> yuuuup z is Long");
        }
    }
}

出力:

---Before Java 8---

z:1

---Since Java 8---
integer overflow
z : 4611686014132420609

> yuuuup z is Long

2.オーバーフローを検出して処理する


integer`のオーバーフローを処理し、

long`のオーバーフローを決定する例です。

MultiplyExact2.java

package com.mkyong.exactmethods;

public class MultiplyExact2 {

    public static void main(String[]args) {

        int x = 1000000;
        int y = 1000000;
        long a = Long.MAX__VALUE;//( = 9 223 372 036 854 775 807)
        long b = Long.MAX__VALUE;
        Object z, c;

        System.out.println("---Before Java 8---");
        z = x **  y;
        c = a **  b;
        System.out.println("z : " + z);
        System.out.println("c : " + c);

        System.out.println("\n---Since Java 8---");
        try {
            z = Math.multiplyExact(x, y);
            c = Math.multiplyExact(a, b);
        } catch (ArithmeticException e) {
            try {
                z = Math.multiplyExact((long) x, (long) y);
                c = null;
            } catch (ArithmeticException ex) {
                z = null;
            }
        }

        if (z instanceof Integer) {
            System.out.println("z is instance of Integer: " + z);
        }
        if (z instanceof Long) {
            System.out.println("z is instance of Long: " + z);
        } else {
            System.out.println("Overflow for z");
        }

        if (c instanceof Integer) {
            System.out.println("Instance of Integer: " + c);
        }
        if (c instanceof Long) {
            System.out.println("Instance of Long: " + c);
        } else {
            System.out.println("Overflow for c");
        }
    }
}

出力:

---Before Java 8---

z:-727379968 c:1

---Since Java 8---
z is instance of Long: 1000000000000
Overflow for c

3.すべてのxxxExactメソッド

すべての新しい `xxxExact`メソッドを示す例

AllExactMethods.java

package com.mkyong.exactmethods;

public class AllExactMethods {

    public static void main(String[]args){
        int x = 10000;
        int y = 10000;
        Object z;

        z = Math.addExact(x, y);
        System.out.println("addExact: " + x + " + " + y + " = " + z);
        z = Math.subtractExact(x, y);
        System.out.println("subtractExact: " + x + " - " + y + " = " + z);
        z = Math.multiplyExact(x, y);
        System.out.println("multiplyExact: " + x + " **  " + y + " = " + z);
        z = Math.incrementExact(x);
        System.out.println("incrementExact: " + x + " + 1 = " + z);
        z = Math.decrementExact(y);
        System.out.println("decrementExact: " + y + " - 1 = " + z);
        z = Math.negateExact(x);
        System.out.println("negateExact: " + x + " **  -1 = " + z);
    }
}

出力:

addExact: 10000 + 10000 = 20000
subtractExact: 10000 - 10000 = 0
multiplyExact: 10000 **  10000 = 100000000
incrementExact: 10000 + 1 = 10001
decrementExact: 10000 - 1 = 9999
negateExact: 10000 **  -1 = -10000

参考文献


  1. https://www.manning.com/books/java-8-in-action

    [“Java 8 in Action”による

Raoul-Gabriel Urma、Mario Fusco、Alan Mycroft]。

https://docs/

Java 8 API]