더북(TheBook)

JDK 8부터 각 원시 수 타입에 래퍼를 추가하면서 + 연산자를 보다 표현적으로 래핑했다. 다시 말해 Integer, Long, Float, Double 클래스에 sum() 메서드가 생겼다.

long z = Long.sum(); // -2

내부적으로 sum() 메서드도 + 연산자를 사용하므로 결국 결과는 같다.

하지만 JDK 8부터 Math 클래스에도 두 개의 addExact() 메서드가 추가됐다. 두 int 변수를 합하는 addExact()와 두 long 변수를 합하는 addExact()다. 두 메서드는 앞선 예제처럼 결과에 intlong 오버플로가 발생하기 쉬울 때 매우 유용하다. 이때 잘못된 결과를 반환하는 대신 아래 예제처럼 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() 외에도 MathmultiplyExact(), substractExact(), negateExact()를 지원한다. 또한 잘 알려진 증감 연산자인 i++i--incrementExact(), decrementExact() 메서드로 도메인 오버플로를 제어할 수 있다(Math.incrementExact(i)처럼 사용한다). 단, 두 메서드는 intlong에만 쓸 수 있다.

TIP ≣ 큰 수를 다룰 때 BigInteger(불변 임의 정밀도(arbitrary-precision) 정수)와 BigDecimal(불변 임의 정밀도 부호 있는 소수) 클래스도 고려하자.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.