JDK 8부터 각 원시 수 타입에 래퍼를 추가하면서 + 연산자를 보다 표현적으로 래핑했다. 다시 말해 Integer, Long, Float, Double 클래스에 sum() 메서드가 생겼다.
long z = Long.sum(); // -2
내부적으로 sum() 메서드도 + 연산자를 사용하므로 결국 결과는 같다.
하지만 JDK 8부터 Math 클래스에도 두 개의 addExact() 메서드가 추가됐다. 두 int 변수를 합하는 addExact()와 두 long 변수를 합하는 addExact()다. 두 메서드는 앞선 예제처럼 결과에 int나 long 오버플로가 발생하기 쉬울 때 매우 유용하다. 이때 잘못된 결과를 반환하는 대신 아래 예제처럼 ArithmeticException을 던진다.
int z = Math.addExact(x, y); // ArithmeticException을 던진다
위 코드는 java.lang.ArithmeticException: integer overflow 같은 예외를 던진다. 뒤이은 계산에서 잘못된 결과를 넣지 않으므로 이러한 예외는 유용하다(가령 아무도 모르게 -2가 뒤이은 계산에 들어갈 수 있다).
함수형 스타일에서는 다음과 같이 BinaryOperator 함수 인터페이스를 사용한다(타입이 같은 두 피연산자 간 연산을 정의하면 된다).
BinaryOperator<Integer> operator = Math::addExact;
int z = operator.apply(x, y);
addExact() 외에도 Math는 multiplyExact(), substractExact(), negateExact()를 지원한다. 또한 잘 알려진 증감 연산자인 i++와 i--도 incrementExact(), decrementExact() 메서드로 도메인 오버플로를 제어할 수 있다(Math.incrementExact(i)처럼 사용한다). 단, 두 메서드는 int와 long에만 쓸 수 있다.
TIP ≣ 큰 수를 다룰 때 BigInteger(불변 임의 정밀도(arbitrary-precision) 정수)와 BigDecimal(불변 임의 정밀도 부호 있는 소수) 클래스도 고려하자.