[Java] 제네릭 활용
2025. 10. 30. 10:32ㆍDev./Java
728x90
반응형
제네릭(Generics)
- 제네릭은 클래스, 메서드, 인터페이스에서 타입을 파라미터로 사용할 수 있게 해주는 기능
- 타입 안정성(type-safety) 제공 + 코드 재사용성을 높임
문법
class Box<T> {
private T value;
public void set(T value) {
this.value = value;
}
public T get() {
return value;
}
}
- <T>는 타입 매개변수(Type Parameter)
- T 자리에 실제 타입이 들어감
제네릭과 Map/Collection
- Map<Key, Value> 구조에서 Key와 Value를 일반화 가능
- K와 V를 제네릭 타입으로 선언하면 다른 타입도 재사용 가능
Map<K, V> map = new HashMap<>();
직접 활용해보기
Cart클래스에 제네릭을 활용해볼 수 있었다.
클래스
public class Cart<K extends MenuItem, V extends CartItem> {}
- extends키워드는 타입 제한 걸 때 사용하는 키워드
- Cart<K,V>는 아무 타입이나 다 올수 있지만 Cart에는 MenuItem 기반 CartItem 만 담아야 하기 때문에 타입 제한 사용
- K는 반드시 MenuItem이거나 그 하위 클래스여야 하고, V는 반드시 CartItem이거나 그 하위 클래스여야 한다
- 타입제한을 두면 getName()같은 MenuItem 내부 메서드 사용 가능
필드 선언
private final Map<K, V> cart = new HashMap<>();
장바구니 아이템 추가
public V addCartItem(K key, int quantity) {
cart.compute(key, (k, existedCartItem) -> {
if (existedCartItem == null) existedCartItem = (V)new CartItem(k);
existedCartItem.increaseQuantity(quantity);
return existedCartItem;
});
return cart.get(key);
}
- 제네릭 사용으로 key,value 타입 고정하지 않고 사용 가능하다.
- (V)new CartItem(k) -> Kiosk 입장에서는 MenuItem과 수량만 전달하면 되기 때문에 Cart가 CartItem을 내부에서 만들어주면 호출이 간단해짐
발견한 문제
existedCartItem = (V) new CartItem(k);
- 이 코드는 컴파일러 순간 CartItem을 V로 변환한다는 의미
- 문제는, V가 CartItem의 하위 클래스일 수도 있기 때문에 런타임 시 ClassCastException이 발생할 위험 가능성 존재
- 예를 들어 SpeciaCartItem 타입으로 캐스팅 하면 런타임 오류가 남
해결
제네릭 단순화로 안전하게 리팩토링
CartItem 하위 타입 없기 때문에 제네릭은 Key 하나로만 유지해 리팩토링
public class Cart<K extends MenuItem> {
private final Map<K, CartItem> cart = new HashMap<>();
public CartItem addCartItem(K key, int quantity) {
cart.compute(key, (k, existedCartItem) -> {
if (existedCartItem == null) existedCartItem = new CartItem(k);
existedCartItem.increaseQuantity(quantity);
return existedCartItem;
});
return cart.get(key);
}
}728x90
반응형
'Dev. > Java' 카테고리의 다른 글
| [Java] 반복문 대신 재귀로 코드의 의도를 드러내기 (0) | 2025.11.03 |
|---|---|
| [Java] 상태 패턴 (State Pattern) (0) | 2025.10.24 |
| [Java] List, 객체를 value로 활용하기 (객체 중첩) (0) | 2025.10.23 |
| [Java] Map, 객체를 value로 활용하기 (객체 중첩) (0) | 2025.10.22 |
| [Java] getter/setter 왜 사용 지양해야할까? (0) | 2025.10.21 |