문제 상황
계산기 프로젝트를 진행하며 정수뿐만 아니라 실수도 연산할 수 있도록 기능을 확장해야 했다.
요구사항에서는 단순히 int를 double로 변경하는 것이 아니라, 제네릭을 활용하여 여러 숫자 타입을 받을 수 있도록 구현할 것을 요구했기 때문에 다음과 같이 ArithmeticCalculator를 제네릭 클래스로 변경하였다.
public class ArithmeticCalculator<T extends Number> {
}
그리고 계산 메서드를 구현하려고 했다.
public T calculate(T num1, T num2) {
return num1 + num2;
}
하지만 컴파일 오류가 발생하였다.
원인 분석
처음에는 제네릭으로 선언했기 때문에 Integer, Double 등 다양한 숫자 타입이 모두 연산 가능할 것이라고 생각했다.
하지만 자바의 제네릭은 컴파일 시점에 타입 정보가 제거(Type Erasure)되며, 컴파일러는 T가 실제로 어떤 숫자 타입인지 알 수 없다.
예를 들어 아래와 같은 코드는 허용되지 않는다.
T result = num1 + num2;
왜냐하면 컴파일러 입장에서는
Integer + Integer
인지,
Double + Double
인지,
Long + Long
인지 판단할 수 없기 때문이다.
즉, 자바는 제네릭 타입에 대해 산술 연산자를 지원하지 않는다.
해결 방법
제네릭 타입을 Number로 제한하고, Number가 제공하는 메서드를 활용하여 계산하도록 수정하였다.
double number1 = num1.doubleValue();
double number2 = num2.doubleValue();
이후 실제 연산은 double 타입으로 수행하였다.
double result = number1 + number2;
최종적으로 계산 메서드는 다음과 같은 형태가 되었다.
public double calculate(T num1, T num2, char operator) {
double number1 = num1.doubleValue();
double number2 = num2.doubleValue();
return number1 + number2;
}
결과
정확히 타입을 지정하고 나니 정상적으로 연산에 성공하였다.
하지만 제네릭을 사용하는 것은 다양한 타입을 받을 수 있다는 장점을 지니는데, double형 메서드를 사용하는 것이 완전성이 떨어지는 거 같아서 아쉬움이 남는다.
과정까지 완전히 제네릭을 제네릭답게 사용할 수 없을지 조금 더 고민을 해보면 좋을 거 같다.
배운 점
이번 구현을 통해 제네릭이 모든 타입 정보를 유지한 채 동작하는 것이 아니라는 점을 알게 되었다.
제네릭은 입력 타입을 유연하게 만들 수는 있지만, 자바에서는 제네릭 타입에 대해 직접 산술 연산을 수행할 수 없다.
따라서 숫자 계산이 필요한 경우에는 Number 클래스의 메서드를 이용하여 적절한 기본형으로 변환한 뒤 연산해야 한다는 점을 학습할 수 있었다.
'TIL' 카테고리의 다른 글
| [TIL] 자바 catch문에는 왜 Exception 타입만 들어갈 수 있을까? (0) | 2026.06.08 |
|---|---|
| [TIL] 시간복잡도는 if문 개수보다 반복 횟수가 중요한 이유 (0) | 2026.06.06 |
| [TIL] 문자열에서 숫자를 추출하고 int로 변환하는 방법 (0) | 2026.06.02 |
| [TIL] 코딩테스트에서 Arrays 클래스가 중요한 이유 (0) | 2026.05.28 |
| [TIL] 코딩테스트를 풀다가 StringBuilder의 필요성을 직접 체감하다. (0) | 2026.05.27 |