언어(Language)/Java
[Java] 제네릭
송기동
2025. 5. 3. 15:18
728x90
제네릭(Generic)
- 데이터 타입을 일반화 하는 기능
- 클래스나 메서드를 만들 때 데이터 타입을 고정하지 않고, 나중에 사용할 때 타입을 지정할 수 있도록 만드는 문법
- 타입은 참조형만 사용 가능
ArrayList<String> list = new ArrayList<String>();
// 여기서 <String> 부분이 제네릭!
# 문법
- 괄호 < > 안에 타입 매개변수(타입 파라미터)를 표시함
- 컴마(,)를 사용해 여러 타입 매개변수를 지정 가능
- 타입 매개변수는 타입을 전달 받기 위한 것
- 타입 파라미터의 이름은 관례적으로 E, K, V, N, T 등을 사용함
접근제어자 class 클래스이름<타입매개변수1, 타입매개변수2, ...> {
...
}
# 제네릭 문법 키워드
문법 | 의미 |
<T> | 타입 매개변수 선언(일반적인 타입) |
<타입 extends 클래스> | 상위 타입 제한 |
<타입 super 클래스> | 하위 타입 허용 (하한 제한) |
<?> | 모든 타입 허용 (읽기 전용) |
<K, V> | 맵의 키-값 페어에 자주 사용 |
<E> | Element (컬렉션 요소)용 (예: List, Set) |
<N> | 숫자 타입에 자주 사용 |
제네릭을 사용하는 이유
1. 코드의 재사용
- 하나의 클래스로 다양 타입을 처리할 수 있음
class Box<T> {
T item;
void set(T item) { this.item = item; }
T get() { return item; }
}
// Box<String>, Box<Integer> 등으로 다양하게 사용 가능!
2. 타입 안정성(Type Safety)
- 컴파일 시점에 타입 오류를 방지해줌
Box<String> strBox = new Box<>();
strBox.set("Hello");
// strBox.set(123); // 오류! 컴파일 타임에 잡힘
3. 형변환 없이 사용
- 제네릭을 안 쓰면 꺼낼 때 형변환(casting)이 필요
ArrayList list = new ArrayList(); // 제네릭 X
list.add("apple");
String fruit = (String) list.get(0); // 형변환 필요
- 제네릭을 쓰면 형변환 없이도 안전하게 사용 가능
ArrayList<String> list = new ArrayList<>();
list.add("apple");
String fruit = list.get(0); // 형변환 필요 없음!
# 제네릭 사용 시 유의사항
번호 | 유의사항 | 설명 |
1️⃣ | 기본형(primitive type)은 사용 불가 | int, double 등은 제네릭에 직접 사용 못함 → Integer, Double 등 래퍼 클래스 사용 |
2️⃣ | 런타임 시 타입 정보는 지워짐 (타입 소거) | 제네릭은 컴파일러에서만 타입 체크하고, 실제 실행 시에는 Object처럼 동작 |
3️⃣ | instanceof로 타입 체크 불가 | if (obj instanceof Box<String>) → ❌ 오류 발생 |
4️⃣ | 제네릭 타입의 배열 생성 불가 | T[] arr = new T[10]; → ❌ 대신 Object[] 생성 후 캐스팅 |
5️⃣ | static 필드에서 제네릭 타입 사용 불가 | static T item; → ❌ (제네릭은 클래스 인스턴스에 따라 달라지므로) |
6️⃣ | 제네릭 타입에 instanceof 사용 시 주의 | instanceof List<?>은 가능, 하지만 타입 파라미터와 비교는 불가 |
7️⃣ | 타입 캐스팅은 컴파일러에게 맡겨야 안전 | 직접 (T) 캐스팅보단 컴파일러의 타입 추론 활용 권장 |
8️⃣ | 와일드카드는 읽기/쓰기 구분 필요 | ? extends T는 읽기 전용, ? super T는 쓰기 가능 |
9️⃣ | 제네릭 메서드 정의 시 <T>를 메서드 앞에 명시 | public static <T> void print(T t)처럼 선언해야 함 |
🔟 | 제네릭 타입은 공변/반공변이 아님 | List<Object>에 List<String>을 대입할 수 없음 (List<?> 사용해야 가능) |
728x90