[이것이 자바다] 12. 제네릭
안녕하세요. 이번에는 자바의 제네릭에 대해 정리한 내용입니다. 제네릭은 배워두면 정말 유용합니다.
1. 제네릭(Generic) 필요성
- 제네릭이 없던 시절에는 자바의 컬렉션에 모든 종류의 객체를 저장하기 위해
Object타입을 사용했습니다.
// 제네릭이 없던 시절
List list = new ArrayList();
list.add("hello"); // String을 넣고
String str = (String) list.get(0); // 꺼낼 때는 String으로 강제 형변환 필요
list.add(100); // 실수로 Integer를 넣어도 컴파일 에러가 발생하지 않음
Integer i = (Integer) list.get(1);
- 불편함: 객체를 꺼낼 때마다, 원래 타입을 기억해서 매번 강제 타입 변환을 해야 합니다.
- 치명적인 위험: 실수로 다른 타입의 객체를 넣어도 컴파일러가 잡지 못합니다. (실행 시
ClassCastException발생 위험)
- 해결책: 클래스나 인터페이스, 메소드를 정의할 때 타입을 파라미터화하여 컴파일 시점에 구체적인 타입을 지정하게 합니다.
2. 제네릭 타입 <T>
- 클래스 또는 인터페이스 이름 뒤
<T>와 같은 타입 파라미터를 붙여 선언합니다. (T는 실제 사용될 타입으로 대체됨) - 목적: 클래스 내부에서 사용될 데이터의 타입을 객체를 생성할 때 결정하여 코드의 안정성을 높입니다.
public class Box<T> {
private T item;
public T getitem() {
return item;
}
public void setitem(T item) {
this.item = item;
}
}
// 사용할 때 구체적인 타입을 지정 (타입 아규먼트)
Box<String> stringBox = new Box<>(); // String만 담을 수 있는 Box
stringBox.setitem("문자열");
String result = stringBox.getitem(); // 강제 형변환이 필요 없음
3. 제네릭 메소드 <T, R>
- 리턴 타입 앞에
<T, ...>와 같이 독자적인 타입 파라미터를 가지는 메소드입니다. - 특징: 클래스가 제네릭 타입이 아니어도, 특정 메소드만 독립적으로 제네릭 적용 가능합니다.
public class Util {
// T 타입의 Box를 받아 그 안의 내용을 리턴하는 제네릭 메소드
public static <T> T unboxing(Box<T> box) {
T item = box.getitem();
return item;
}
}
4. 제한된 타입 파라미터
<T extends 상위타입>- 제네릭에 사용될 수 있는 타입을 특정 클래스 또는 그 자식 클래스들로만 제한합니다.
- 복적
- 타입 제한: 아무 타입이나 들어오는 것을 막고, 의도한 타입 계층 내의 객체만 받도록 강제합니다.
- 메소드 접근: 상위 타입에 선언된 메소드를 제네릭 코드 안에서 안전하게 사용 가능합니다.
// Number 클래스 또는 그 자식(Integer, Double 등)만 타입으로 받을 수 있음
public static <T extends Number> int compare(T t1, T t2) {
// T가 Number의 자식임이 보장되므로, Number의 메소드인 doubleValue()를 안전하게 호출 가능
double v1 = t1.doubleValue();
double v2 = t2.doubleValue();
return Double.compare(v1, v2);
}
5. 와일드카드 타입
<?>,<? extends ...>,<? super ...>- 제네릭 타입을 메소드의 매개변수나 리턴 타입으로 사용할 때, 구체적인 타입 대신 사용할 수 있는 범용적인 표현입니다.
- 목적: 제네릭을 사용하는 코드의 유연성을 극대화하기 위함입니다.
<?>: 타입에 제한이 없음. 어떤 타입이든 매개변수로 받을 수 있습니다. (주로 읽기 전용)<? extends 상위타입>:상위타입또는 그 자식 타입들만 가능합니다.<? super 하위타입>:하위타입또는 그 부모 타입들만 가능합니다.
핵심 포인트
- 제네릭의 존재 이유
- 컴파일 시점의 타입 안정성 확보
- 컴파일 에러로 사전에 문제 발견 가능
<T extends Number>- 제네릭 범위 제한 (
Number이거나 그 자식만 허용)
- 제네릭 범위 제한 (
- 와일드카드(
?)- 메소드의 매개변수 등에서 다양한 제네릭 타입을 유연하게 받기 위해 사용
감사합니다.
'Language > JAVA' 카테고리의 다른 글
| [이것이 자바다].ch14.컬렉션 (0) | 2025.12.30 |
|---|---|
| [이것이 자바다].ch13.스레드 (0) | 2025.12.30 |
| [이것이 자바다].ch11.java.base 모듈 (0) | 2025.12.29 |
| [이것이 자바다].ch10.예외처리 (0) | 2025.12.28 |
| [이것이 자바다].ch9.라이브러리 (0) | 2025.12.28 |