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
参考文献
-
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]