[JAVA] 자바 제네릭 메서드와 와일드카드, 그리고 타입 이레이저

2025. 7. 16. 17:07·자바

자바의 제네릭(Generic)은 코드의 재사용성과 안정성을 높이기 위해 사용된다. 특히 메서드 레벨에서의 제네릭 메서드, 제네릭 타입을 유연하게 사용할 수 있는 와일드카드, 컴파일 이후 제네릭 정보가 사라지는 타입 이레이저는 꼭 알아야 할 핵심 개념이다.

이 글에서는 각 개념을 실제 코드와 함께 이해하기 쉽게 설명한다.

 

1. 제네릭 메서드란?

제네릭 메서드(Generic Method)는 메서드에서 사용할 타입을 미리 정하지 않고, 메서드를 호출하는 시점에 타입을 전달받는 방식이다.

예시 코드:

public class GenericMethod {
    public static <T> T printAndReturn(T value) {
        System.out.println("value = " + value);
        return value;
    }
}

사용:

Integer result1 = GenericMethod.printAndReturn(10);        // T는 Integer
String result2 = GenericMethod.printAndReturn("Hello");    // T는 String

 

핵심 포인트

  • <T>는 메서드 안에서 사용할 타입 매개변수
  • 호출 시 넘겨주는 인자의 타입에 따라 자동으로 T가 결정됨 (타입 추론)
  • 필요하면 <T extends Number>처럼 상한 제한도 가능

 

2. 와일드카드란?

와일드카드(Wildcard)는 제네릭 타입을 사용할 때 정확한 타입을 몰라도 객체를 받을 수 있게 해주는 문법이다. 물음표(?)로 표현한다.

 

배경 설명

자바의 제네릭은 타입이 다르면 다른 타입으로 간주하기 때문에, 서로 다른 제네릭 타입끼리는 호환되지 않는다.

예를 들어 다음 코드는 오류다.

public void printBox(Box<Object> box) {
    System.out.println(box.get());
}

Box<String> stringBox = new Box<>();
printBox(stringBox); // 오류: Box<Object> ≠ Box<String>

→ Box<String>은 Box<Object>의 자식이 아니기 때문.

 

해결: 와일드카드 사용

public void printBox(Box<?> box) {
    System.out.println(box.get());
}

이제 Box<String>, Box<Integer>, Box<Dog> 등 모든 타입의 Box를 받을 수 있다.
즉, ?는 "타입은 모르겠지만 뭐든 괜찮다"는 의미다.

 

상한 와일드카드 (? extends 타입)

public void printAnimalName(Box<? extends Animal> box) {
    Animal animal = box.get();           // 안전하게 꺼내기 가능
    System.out.println(animal.getName());
}

 

  • Box<Dog>, Box<Cat> 등은 OK
  • Box<Object>는 컴파일 오류
  • 값을 꺼낼 때는 안전, 하지만 넣을 수는 없음

하한 와일드카드 (? super 타입)

 

특정 타입과 그 부모 타입만 허용한다.

public void addDog(Box<? super Dog> box) {
    box.set(new Dog("멍멍이", 100));    // 안전하게 넣기 가능
}
  • Box<Dog>, Box<Animal>, Box<Object>는 OK
  • Box<Cat>은 컴파일 오류
  • 값을 넣을 수는 있지만, 꺼낼 때는 Object로 받아야 함

 

정리: 제네릭 메서드 vs 와일드카드

구분                            제네릭 메서드                                                      와일드카드
선언 위치 <T> T method(T t) void method(Box<? ...> box)
용도 타입을 직접 제어하고 싶을 때 유연하게 다양한 타입을 받기 위해
반환 타입 가능 거의 불가능 (Object 수준)
타입 추론 가능 불가능
코드 복잡도 복잡 간단
 
  • 제네릭 메서드: 값을 받고, 연산하고, 결과를 그대로 반환하는 등 타입을 적극적으로 쓸 때
  • 와일드카드: 단순히 값을 꺼내서 출력하거나 저장할 때

 

3. 타입 이레이저(Type Erasure)

자바는 컴파일 이후에 제네릭 정보를 모두 지운다. 이를 타입 이레이저(Type Erasure)라고 한다.

 

예시코드:

GenericBox<Integer> box = new GenericBox<>();
box.set(10);
Integer result = box.get();

 

컴파일 후에는 이렇게 바뀐다고 보면 된다:

GenericBox box = new GenericBox();           // 타입 정보 제거
box.set((Object) 10);
Integer result = (Integer) box.get();        // 컴파일러가 캐스팅 추가

 

핵심 포인트

  • 제네릭은 컴파일 타임에만 존재
  • 런타임에는 모든 타입 정보가 사라짐
  • 그래서 다음과 같은 코드는 불가능
public boolean isInstance(Object obj) {
    return obj instanceof T;   // 오류
}

public T create() {
    return new T();           // 오류
}
  • T는 런타임에 존재하지 않기 때문에 instanceof T, new T()는 컴파일 오류가 난다
  • 대신 컴파일러가 자동 캐스팅 코드를 삽입해주기 때문에, 우리가 따로 캐스팅하지 않아도 안전하게 사용할 수 있다

 

마무리하며:

자바에서 제네릭은 복잡해 보일 수 있지만, 핵심은 명확하다.
타입을 정밀하게 다루고자 할 땐 제네릭 메서드,
여러 타입을 유연하게 받아야 할 땐 와일드카드,


그리고 제네릭은 컴파일 타임에만 존재하며, 런타임에는 사라진다는 사실(타입 이레이저)을 기억하자.

특히 와일드카드는 “타입을 몰라도 괜찮을 때”, 즉 단순히 값을 꺼내서 사용하는 읽기 전용 메서드에 적합하다.


반면 제네릭 메서드는 “타입을 알고, 다루고, 반환하고 싶은 경우”에 꼭 필요하다.
타입 추론, 타입 보존, 반환 타입 제어 등 정밀한 작업이 가능하기 때문이다.

 

이처럼 상황에 따라 와일드카드와 제네릭 메서드를 적절히 선택하는 것이 자바 제네릭을 효과적으로 활용하는 핵심이다.
제네릭은 타입 안정성과 코드 재사용성을 모두 높이는 중요한 도구다.
개발자가 타입을 직접 다루는 데 필요한 무기이자, 동시에 실수를 방지해주는 안전장치다.

 

 

감사합니다.

 

'자바' 카테고리의 다른 글

[JAVA] List에 인터페이스에 대하여 (2)  (5) 2025.07.18
[JAVA] 배열의 단점과 ArrayList, LinkedList 비교 (1)  (4) 2025.07.17
[JAVA] 제네릭이 필요한 이유  (1) 2025.07.14
[JAVA] 예외 처리4 -실무  (4) 2025.07.12
[JAVA] 예외 처리3 -실습  (1) 2025.07.11
'자바' 카테고리의 다른 글
  • [JAVA] List에 인터페이스에 대하여 (2)
  • [JAVA] 배열의 단점과 ArrayList, LinkedList 비교 (1)
  • [JAVA] 제네릭이 필요한 이유
  • [JAVA] 예외 처리4 -실무
0kingki_
0kingki_
자바 + 스프링 웹 개발
  • 0kingki_
    0kingki_
    0kingki_
  • 전체
    오늘
    어제
    • 분류 전체보기 (134)
      • 코딩 테스트 (54)
      • 자바 (21)
      • 스프링 (27)
      • 타임리프 (16)
      • 스프링 데이터 JPA (8)
      • 최적화 (2)
      • QueryDSL (4)
      • AWS (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Java
    LocalDateTime
    dfs
    최적화
    예외 처리
    코딩 테스트
    객체지향
    thymeleaf
    스프링
    쿼리dsl
    mvc
    spring
    불변객체
    JPA
    BFS
    SOLID
    재귀
    백준
    다형성
    스프링 컨테이너
    스프링 데이터 JPA
    예외처리
    자바
    QueryDSL
    타임리프
    fetch join
    코딩테스트
    SpringDataJpa
    쿼리
    컬렉션
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
0kingki_
[JAVA] 자바 제네릭 메서드와 와일드카드, 그리고 타입 이레이저
상단으로

티스토리툴바