반응형
Java 제네릭(Generic) — 캐스팅을 없애고 타입 검사를 컴파일 단계로 옮기기
이 글은 2022년 5월 기준 기록입니다.
Java는 부모 타입이 자식 타입을 모두 담을 수 있도록 함으로써 다형성을 구현합니다. 편리한 성질이지만 대가가 있습니다.
다형성은 꺼내 쓸 때 값을 치릅니다
부모 타입에 담긴 자식 타입은 각각의 타입으로 변환이 되어야 자식이 가지는 기능을 활용할 수 있습니다. 그래서 보통 instanceof 예약어로 자식 객체의 타입을 확인한 뒤 캐스팅해서 쓰게 됩니다.
문제는 이 타입 확인이 번거롭다는 점입니다. 담을 때는 편했는데 꺼낼 때마다 확인과 형변환을 반복해야 합니다. 그래서 Java는 컴파일 단계에서 컴파일러가 타입 체크를 엄격하게 할 수 있도록 Generic 기능을 제공합니다.
제네릭이 없으면 Object로 담고 매번 캐스팅합니다
제네릭 타입을 사용하지 않는 Box는 내용물을 Object 타입으로 담습니다.
public class Box {
private Object object;
public void set(Object object) { this.object = object; }
public Object get() { return object; }
}
Box box = new Box();
box.set("hello"); // String 타입을 Object 타입으로 자동 타입 변환해서 저장
String str = (String) box.get(); // Object 타입을 String 타입으로 강제 타입 변환해서 얻음
넣을 때는 자동 타입 변환이라 조용히 넘어가지만, 꺼낼 때는 (String) 강제 타입 변환이 필요합니다. 그리고 이 캐스팅이 맞는지는 컴파일러가 보장해 주지 않습니다.
제네릭은 타입을 미리 못 박아 캐스팅을 지웁니다
타입 파라미터 T를 두면 이야기가 달라집니다.
public class Box<T> {
private T t;
public T get() { return t; }
public void set(T t) { this.t = t; }
}
이 한 벌의 코드가 사용하는 쪽에서 지정한 타입에 맞춰 전개됩니다.

Box<String> box = new Box<String>();이라고 쓰면 컴파일러는 T 자리가 전부 String으로 바뀐 클래스처럼 취급합니다.
Box<String> box = new Box<String>();
box.set("hello");
String str = box.get();
Box<Integer> box = new Box<Integer>();
box.set(6);
int value = box.get();
제네릭 타입을 사용하면 컴파일 단계에서 자동으로 지정 타입으로 변환되므로 캐스팅이 필요 없습니다. 꺼내는 자리의 괄호가 사라진 것이 눈에 보이는 변화이고, 타입이 어긋나면 실행 전에 걸린다는 것이 보이지 않는 변화입니다.
반응형
'IT·테크 > 개발' 카테고리의 다른 글
| Java 예외 처리 — 일반 예외와 실행 예외를 가르는 기준 (0) | 2026.07.27 |
|---|---|
| Java Wrapper 클래스 — 기본 타입을 객체로 다루는 박싱과 언박싱 (0) | 2026.07.26 |
| 자바 클래스 정리 — 필드·생성자·메소드부터 어노테이션까지 (0) | 2026.07.24 |
| 자바 조건문과 반복문 — if·switch·for·while 흐름 제어 (0) | 2026.07.23 |
| Git 기본기 — 스테이징부터 되돌리기와 브랜치까지 (0) | 2026.07.22 |