과제를 수행하다가 제네릭에서 타입에 extends를 걸 수 있다는 사실을 알았습니다.
그래서 이전에 제네릭 타입T에 사칙연산을 해줄 수 없어서 형변환을 아래와 같은 방식으로 만들어 주었는데
double number1 = Double.parseDouble(positiveNumber1.toString());
아그럼이제 그럴 필요 없겠다! 생각을했습니다.
하지만 여전히 "연자사 '+' 를 "T","T"에 적용할 수 없습니다. 라는 에러가 발생하였고,
엥? 똑같이 안되네? 하고 왜 안되는건지 찾아봤습니다.
일단
<T extends Number>
의 진짜 의미는 T는 Number의 하위 타입이다.
즉 T는 아래 중 하나 일 수 있습니다 :
Integer
Double
Long
BigDecimal
AtomicInteger
Byte
Short
...
하지만! 이 타입들은 공통으로 가진 연산 메서드가 없습니다.
*Number에는 +, -, , / 같은 연산이 정의되어 있지 않다.
즉 Java입장에서 T는 BigDecimal 일 수도, Integer , AtomicInteger 일수도 있는것입니다.
이 타입들은 연산 규칙이 다 다르기 때문에 java가
positiveNumber1 + positiveNumber2 같은 코드를 허용하지 않는 것입니다.
그럼 왜 extends Number를 사용하는가?
"이 T는 숫자이다" 라는 것을 컴파일러에게 증명하기 위해서인데.
기존에 형변환을 조금 복잡한 방식으로 해주었는데.지금 코드를 보면
Double.parseDouble(positiveNumber1.toString())
//Double 객체를 불러서
//그안에 있는 형변환 메서드 호출
//그리고 positiveNumber1 의 타입을 모르니 String으로 변환
이런식으로 코드가 짜여져있다.
하지만 이제는 Number의 하위 타입이란 것을 Java가 알았으니,
double number1 = positiveNumber1.doubleValue();
같은 Number 내장 함수를 사용 할 수있는것이다.
public class Calculator <T extends Number> {
private ArrayList<T> calculateResult = new ArrayList<>();
public double CalculateNumber(T positiveNumber1, T positiveNumber2 , OperatorType operator) {
double number1 = positiveNumber1.doubleValue();
double number2 = positiveNumber2.doubleValue();
return switch (operator) {
case OperatorType.PLUS -> number1 + number2;
case OperatorType.MINUS -> number1 - number2;
case OperatorType.MULTIPLY -> number1 * number2;
case OperatorType.DIVIDE -> {
if (number2 == 0) {
throw new ArithmeticException("0으로는 나눌 수 없습니다.");
}
yield number1 / number2;
}
};
}
그리고 extends Number가 없다면...
Calculator c = new Calculator(); // raw type
c.CalculateNumber("hello", new Dog(), PLUS);
이런 끔찍한...코드도..컴파일러 단계에서 오류를 잡아주지 못한다...

그래서 제네릭의 진짜 목적은 "이 계산기는 여러 타입을 받을 수 있지만 그 타입들은 숫자만 다룬다" 라는 보증서? 계약서? 를 작성하는것과 같다고 생각합니다.
'이슈' 카테고리의 다른 글
| [트러블 슈팅] spring swagger 버전 이슈 ControllerAdviceBean (0) | 2026.02.05 |
|---|---|
| [트러블 슈팅] "List.add()해도 추가되지 않는 이슈" - 불변 객체 건드리기. (1) | 2026.01.22 |
| 책임과 역할을 적절하게 분배하지 못한 이슈 (0) | 2026.01.21 |
| [트러블슈팅]java.lang.NullPointerException: Cannot invoke "java.util.List.stream()" because "this.items" is null (1) | 2026.01.21 |
| Next.js 서버컴포넌트(SSR)에서 서버 통신시 쿠키 세팅 안됨이슈 (0) | 2025.12.16 |