자바에서 형변환(casting)은 서로 다른 타입 간에 값을 변환하는 과정이다.
그런데 형변환을 할 때 대상 타입이 표현할 수 있는 범위를 넘어서는 값이 들어오면 어떤 일이 발생할까?
이때 등장하는 개념이 바로 오버플로우(Overflow) 이다.
형변환 예제로 보는 문제 상황
다음 코드는 long 타입 값을 int 타입으로 형변환하는 예제이다.
public class Casting3 {
public static void main(String[] args) {
long maxIntValue = 2147483647; // int 최대값
long maxIntOver = 2147483648L; // int 최대값 + 1
int intValue = 0;
intValue = (int) maxIntValue;
System.out.println("maxIntValue casting=" + intValue);
intValue = (int) maxIntOver;
System.out.println("maxIntOver casting=" + intValue);
}
}
출력 결과
maxIntValue casting=2147483647
maxIntOver casting=-2147483648
같은 형변환인데 결과는 전혀 다르게 나온다.
정상 범위에서의 형변환
long maxIntValue = 2147483647;
2147483647은 int 타입이 표현할 수 있는 최댓값이다.
즉, 이 값은 int 범위 안에 포함된다.
intValue = (int) maxIntValue;
이 형변환은 아무 문제가 없다.
과정은 다음과 같다.
intValue = (int) 2147483647L;
intValue = 2147483647;
- 값이 int 범위 안에 있다
- 단순히 타입만 바뀐다
- 값의 손실이 없다
이것이 안전한 형변환이다.
범위를 초과한 형변환과 오버플로우
long maxIntOver = 2147483648L;
이 값은 int의 최댓값보다 1 큰 값이다.
이미 int 범위를 초과했기 때문에 리터럴 뒤에 L을 붙여 long 타입으로 선언했다.
이 값을 int로 형변환하면 다음 코드가 실행된다.
intValue = (int) maxIntOver;
내부적으로는 다음과 같은 일이 일어난다.
intValue = (int) 2147483648L;
그 결과는
`-2147483648`
이다.
왜 이런 값이 나올까?
int 타입은 32비트 정수이다.
표현할 수 있는 범위는 다음과 같다.
- 최소값: -2147483648
- 최대값: 2147483647
2147483648은 이 범위를 벗어난다.
자바는 이 값을 억지로 int에 담으려고 하면서 비트만 남기고 잘라낸다.
그 결과 값이 마치 시계가 한 바퀴 도는 것처럼 최소값으로 돌아간다.
이 현상을 오버플로우(Overflow) 라고 한다.
즉,
- 최대값을 넘어가면
- 다시 최소값부터 시작한다
결과를 계산하지 마라
오버플로우가 발생했을 때 결과가 무엇인지 계산하려고 하지 말자
- -2147483648이 왜 나왔는지 분석하는 것은 의미가 없다
- 오버플로우 자체가 이미 버그 상황이다
- 결과값을 믿어서는 안 된다
오버플로우는 조용히 발생하고,
컴파일 에러도 나지 않기 때문에 더 위험하다.
오버플로우를 막는 방법
해결 방법은 단순하다.
int intValue;
대신
long intValue;
처럼 더 큰 범위를 가진 타입을 사용하면 된다.
즉,
- 값이 커질 가능성이 있다면
- 처음부터 충분히 큰 타입을 선택해야 한다
타입을 키우는 것만으로도 오버플로우 문제는 해결된다.
정리
- 형변환 시 대상 타입의 범위를 반드시 고려해야 한다
- 범위를 초과하면 오버플로우가 발생한다
- 오버플로우는 값이 깨지는 현상이다
- 결과를 계산하려 하지 말고, 발생 자체를 막아야 한다
- 해결책은 더 큰 타입을 사용하는 것이다
'김영한 > 자바 입문' 카테고리의 다른 글
| 배열의 선언과 생성 (0) | 2026.02.09 |
|---|---|
| Scanner (0) | 2026.02.09 |
| 스코프 (0) | 2026.02.09 |
| 변수 선언과 초기화 (0) | 2026.02.08 |
| 자바란? (0) | 2026.02.08 |