학습
Java 제네릭 (Generics)
Java 제네릭 (Generics) — 중급
제네릭 (Generics)
1. 도입 (왜 배워야 하는가)
제네릭은 Java에서 매우 중요한 개념으로, 타입 안전성을 제공하고 코드의 재사용성을 높여줍니다. 실무에서는 다양한 데이터 타입을 다루는 경우가 많기 때문에, 제네릭을 이용하면 코드에서 발생할 수 있는 타입 관련 오류를 컴파일 타임에 미리 잡아낼 수 있습니다. 만약 제네릭을 사용하지 않는다면, 타입 캐스팅을 수동으로 처리해야 하며, 이로 인해 런타임 시 오류가 발생할 확률이 높아집니다. 예를 들어, 리스트에서 Integer와 String을 혼용하여 저장할 경우, 잘못된 타입을 꺼낼 때 ClassCastException이 발생할 수 있습니다.
2. 핵심 개념 설명
제네릭은 클래스나 메서드가 사용할 데이터 타입을 매개변수화하여 재사용할 수 있도록 하는 기능입니다. 이를 통해 코드의 유연성과 타입 안전성을 높일 수 있습니다.
- 타입 매개변수: 제네릭 클래스나 메서드에서 사용할 데이터 타입을 나타내는 변수입니다. 예를 들어,
T는 흔히 사용되는 타입 매개변수입니다. - 타입 안전성: 컴파일 타임에 타입 오류를 검출할 수 있어, 런타임 오류를 예방할 수 있게 해줍니다.
| 용어 | 설명 |
|---|---|
| 제네릭 클래스 | 타입 매개변수를 가지는 클래스 |
| 제네릭 메서드 | 타입 매개변수를 가지는 메서드 |
| 와일드카드 | 제네릭 타입으로 특정 범위를 지정할 때 사용하는 기호 ? |
3. 기본 코드 예제
제네릭의 가장 기본적인 사용법을 보여주는 예제입니다.
// 제네릭 클래스를 정의합니다.
class Box<T> {
private T item;
public void setItem(T item) {
this.item = item;
}
public T getItem() {
return item;
}
}
public class Main {
public static void main(String[] args) {
// Integer 타입을 사용하는 Box를 생성합니다.
Box<Integer> integerBox = new Box<>();
integerBox.setItem(10);
System.out.println(integerBox.getItem()); // 10
// String 타입을 사용하는 Box를 생성합니다.
Box<String> stringBox = new Box<>();
stringBox.setItem("안녕하세요");
System.out.println(stringBox.getItem()); // 안녕하세요
}
}
실행 결과:
10
안녕하세요
Box<T>: 제네릭 클래스를 정의하며, T는 타입 매개변수입니다.setItem(T item): item을 Box에 저장하는 메서드입니다.getItem(): 저장된 item을 반환하는 메서드입니다.main 메서드에서는 Integer와 String 타입의 Box 객체를 생성하고, 각각의 아이템을 설정하고 출력합니다.4. 실전 활용 예제
- 쇼핑몰 장바구니 구현
- 제네릭 메서드
- 제네릭 타입을 사용할 때 타입 매개변수를 생략하는 경우
- 와일드카드를 잘못 사용한 경우
- 제네릭을 사용하면 타입 안전성을 확보할 수 있다.
- 코드의 재사용성을 높여주며, 다양한 데이터 타입을 처리할 수 있다.
- 제네릭 클래스와 메서드를 통해 유연한 프로그래밍이 가능하다.
장바구니에 여러 종류의 상품을 담을 수 있도록 제네릭을 사용합니다.
class Cart<T> {
private List<T> items = new ArrayList<>();
public void addItem(T item) {
items.add(item);
}
public List<T> getItems() {
return items;
}
}
이 코드는 다양한 타입의 상품을 담는 장바구니를 구현할 수 있습니다. 예를 들어, Cart<Product>를 사용하여 제품을 담을 수 있습니다.
제네릭 메서드를 정의하여 다양한 타입의 배열을 처리할 수 있습니다.
public static <T> void printArray(T[] array) {
for (T element : array) {
System.out.println(element);
}
}
이 메서드는 어떤 타입의 배열이든 출력할 수 있습니다. printArray(new Integer[]{1, 2, 3})와 같이 호출할 수 있습니다.
5. 흔한 실수와 주의사항
- 잘못된 코드:
Box box = new Box(); // 제네릭 타입을 사용하지 않음
- 올바른 코드:
Box<Integer> box = new Box<>(); // 타입 매개변수를 지정
- 잘못된 코드:
List<?> list = new ArrayList<Integer>();
list.add(1); // 컴파일 오류
- 올바른 코드:
List<? super Integer> list = new ArrayList<Number>();
list.add(1); // 올바르게 추가됨
6. 정리
다음에 학습하면 좋은 주제는 컬렉션 프레임워크입니다. 제네릭과 함께 Java의 컬렉션을 더 깊이 이해하면 실무에 큰 도움이 될 것입니다.