TIL

[Troubleshooting] 자바 제네릭 T 타입으로 사칙연산이 불가능한 이유

기억지기 개발자 2026. 6. 8. 15:56

문제 상황

계산기 프로젝트를 진행하며 정수뿐만 아니라 실수도 연산할 수 있도록 기능을 확장해야 했다.

요구사항에서는 단순히 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 클래스의 메서드를 이용하여 적절한 기본형으로 변환한 뒤 연산해야 한다는 점을 학습할 수 있었다.