In Java 8 kommen neue Methoden hinzu, die eine Überlauferkennung ermöglichen. Die Methoden gibt es in Math und StrictMath:
class java.lang.Math
class java.lang.StrictMath
· static int addExact(int x, int y)
· static long addExact(long x, long y)
· static int subtractExact(int x, int y)
· static long subtractExact(long x, long y)
· static int multiplyExact(int x, int y)
· static long multiplyExact(long x, long y)
· static int toIntExact(long value)
Alle Methoden werfen eine ArithmeticException, falls die Operation nicht durchführbar ist, die letzte zum Beispiel, wenn (int)value != value ist. Leider deklariert Java keine Unterklassen wie UnderflowException oder OverflowException, und Java meldet nur alles vom Typ ArithmeticException mit der Fehlermeldung „xxx overflow“, auch wenn es eigentlich ein Unterlauf ist.
Beispiel: Von der kleinsten Ganzzahl mit subtractExact(…) eins abzuziehen führt zur Ausnahme:
subtractExact( Integer.MIN_VALUE, 1 ); // ArithmeticException
In Math, aber nicht in StrictMath, gibt es weiterhin:
class java.lang.Math
· static int incrementExact(int a)
· static long incrementExact(long a)
· static int decrementExact(int a)
· static long decrementExact(long a)
· static int negateExact(int a)
· static long negateExact(long a)
Kann wegen des Wertebereiches die Operationen nicht durchgeführt werden, folgt wieder eine ArithmeticException.
Vergleich mit C#: C# verhält sich genauso wie Java und reagiert standardmäßig nicht auf Überlauf. Es gibt jedoch spezielle checked-Blöcke, die eine OverflowException melden, wenn es bei arithmetischen Grundoperationen zu einem Überlauf kommt. Folgendes löst diese Ausnahme aus: checked { int val = int.MaxValue; val++; }. Solche checked-Blöcke gibt es in Java nicht, wer diese besondere Überlaufkontrolle braucht, muss die Methoden nutzen, und ein val++ dann auch umschreiben zu Math.addExact(val, 1) bzw. Math.incrementExact(val);
Schön zu sehen, dass viele Verbesserungen aus Google Guava in Java 8 gelandet sind, in diesem Fall also die Math Utilities.