본문 바로가기
language/java

Java Generic(제네릭) 기초 완벽 이해하기

by 죄니안죄니 2026. 5. 27.
반응형

Java Generic(제네릭) 기초 완벽 이해하기

Java를 공부하다 보면 반드시 만나게 되는 문법이 바로:

 
List<String>
Map<String, Integer>
 

같은:

Generic(제네릭)

입니다.

처음에는 단순히:

타입 적는 문법?
 

정도로 보이지만,

실제로 Generic은 Java 타입 시스템의 핵심 기술 중 하나입니다.

특히 실무에서는:

  • 타입 안정성(Type Safety)
  • 컴파일 오류 방지
  • Collection 설계
  • 라이브러리 API
  • Stream API
  • Spring Framework

전체와 깊게 연결됩니다.

이번 글에서는:

  • Generic이 왜 필요한가
  • Generic 기본 문법
  • 타입 안정성
  • Generic 메서드
  • Type Erasure
  • 실무 주의점

까지 깊게 정리해보겠습니다.


1. Generic이란?

Generics in Java 는:

클래스나 메서드에서 타입을 외부로부터 받는 문법

입니다.

즉:

“타입을 나중에 결정”
 

하는 구조.


2. 왜 Generic이 필요할까?

Generic 없던 시절(Java 5 이전) 문제부터 보겠습니다.


3. Generic 없던 코드

 
List list = new ArrayList();

list.add("Java");
list.add(100);
 

문제:

아무 타입이나 저장 가능
 

4. 꺼낼 때 문제

 
String value = (String) list.get(1);
 

결과:

ClassCastException
 

발생.


5. 왜 위험할까?

컴파일 시점에는:

오류 발견 불가능
 

하기 때문.

즉:

런타임 오류
 

발생.


6. 그래서 등장한 Generic

핵심 목표:

컴파일 시 타입 체크
 

입니다.


7. Generic 사용 예시

 
List<String> list =
    new ArrayList<>();
 

의미:

String만 저장 가능
 

8. 이제 잘못된 코드

 
list.add(100);
 

결과:

컴파일 오류
 

즉:

런타임 전에 오류 발견
 

가능.


9. 이것이 타입 안정성(Type Safety)

매우 중요.

Generic 핵심 목적:

잘못된 타입 사용 방지
 

입니다.


10. Generic 기본 문법

대표 형태:

 
Class<T>
 

11. T는 무엇인가?

Type
 

의 약자.

즉:

“나중에 실제 타입으로 치환”
 

됩니다.


12. Generic 클래스 예시

 
class Box<T> {

    private T value;

    public void set(T value) {
        this.value = value;
    }

    public T get() {
        return value;
    }
}
 

13. 사용 예시

 
Box<String> box =
    new Box<>();

box.set("Java");

String value = box.get();
 

14. 왜 강력할까?

현재:

캐스팅 불필요
 

합니다.

즉:

컴파일러가 타입 보장
 

가능.


15. 여러 타입 사용 가능

 
Box<Integer>
Box<User>
Box<Long>
 

전부 가능.


16. Generic 타입 이름 관례

자주 사용하는 문자:


문자 의미
T Type
E Element
K Key
V Value
R Return

17. Map 예시

 
Map<String, Integer>
 

의미:

K = String
V = Integer
 

18. Generic 메서드란?

클래스 자체가 아니라:

메서드만 Generic
 

가능.


19. 예시

 
public <T> T print(T value) {

    return value;
}
 

20. 사용 예시

 
String s = print("Java");

Integer n = print(10);
 

21. Generic과 Collection

Collection Framework 거의 전부 Generic 기반.

예:

 
List<String>
Set<User>
Map<String, Long>
 

22. Generic 이전 Collection 문제

예전엔:

 
Object
 

기반.

즉:

꺼낼 때 매번 캐스팅
 

필요.


23. Generic 덕분에

컴파일러가:

자동 타입 체크
 

수행 가능.


24. Type Erasure란?

매우 중요합니다.

Type erasure 는:

컴파일 후 Generic 타입 정보 제거되는 것

입니다.


25. 왜 제거할까?

Java는:

하위 호환성(backward compatibility)
 

유지 필요했기 때문.


26. 실제 컴파일 후

예:

 
List<String>
 

컴파일 후 사실상:

 
List
 

수준으로 동작.


27. 그래서 발생하는 제한

매우 중요.


1) new T() 불가능

 
new T()
 

불가능.

왜냐하면:

런타임에 T 정보 없음
 

28. 2) instanceof 제한

 
obj instanceof List<String>
 

불가능.

이유 동일.


29. 3) static에 Generic 사용 제한

 
static T value;
 

불가능.

왜냐하면:

static은 클래스 공용
 

인데 Generic 타입은 객체별 다를 수 있음.


30. Generic과 캐스팅

컴파일러는 내부적으로:

자동 캐스팅 코드 생성
 

합니다.


31. 그래서 경고 발생 가능

예:

 
List rawList = new ArrayList();
 

결과:

unchecked warning
 

발생 가능.


32. Raw Type이란?

 
List
 

처럼 Generic 타입 생략한 것.


33. 왜 위험할까?

타입 안정성 깨짐
 

가능.

실무에서는 거의 사용 안 함.


34. Diamond Operator(<>)란?

Java 7 이후 추가.

예:

 
List<String> list =
    new ArrayList<>();
 

35. 왜 편할까?

컴파일러가:

타입 추론
 

가능하기 때문.


36. Generic 장점


장점 설명
타입 안정성 O
캐스팅 제거 O
컴파일 오류 검출 O
재사용성 증가 O

37. Generic 단점/제한


제한 이유
new T() 불가 Type Erasure
instanceof 제한 런타임 타입 없음
primitive 직접 사용 불가 Object 기반

38. primitive 왜 안 될까?

 
List<int>
 

불가능.

왜냐하면 Generic은:

Object 기반
 

이기 때문.


39. 대신 Wrapper 사용

 
List<Integer>
 

사용.


40. 실무에서 자주 사용하는 Generic

대표 사례:

 
ResponseEntity<T>
Optional<T>
List<T>
Map<K, V>
 

41. Spring에서도 매우 중요

Spring Framework 내부도 Generic 적극 활용.

예:

 
ResponseEntity<User>
 

42. Generic과 Stream API

예:

 
Stream<String>
 

즉:

타입 안전 Stream 처리
 

가능.


43. 실무에서 자주 하는 실수

1) Raw Type 사용

타입 안정성 깨짐.


2) unchecked warning 무시

런타임 오류 가능.


3) Generic과 runtime 타입 혼동

Type Erasure 이해 부족 때문.


44. 핵심 흐름 요약

Generic 선언
↓
컴파일 시 타입 체크
↓
자동 캐스팅 생성
↓
컴파일 후 Type Erasure
 

45. 가장 중요한 핵심 한 줄

Generic은
“컴파일 시 타입 안정성을 제공하기 위한 Java 타입 시스템”
 

입니다.


46. 정리

Generic은 단순 문법 설탕(Syntactic Sugar)이 아닙니다.

실제로는:

  • 타입 안정성
  • Collection Framework
  • 컴파일러 타입 검사
  • Type Erasure
  • Stream/Spring 타입 시스템

전체와 연결되는 Java 핵심 기술입니다.

특히 실무에서는:

  • Raw Type 위험성
  • Generic 메서드
  • Type Erasure
  • Wrapper 타입
  • 컴파일 타입 안정성

을 정확히 이해하는 것이 매우 중요합니다.

다음 글에서는:

Wildcard (<? extends T>, <? super T>)

를 PECS 원칙, Producer/Consumer, Collection 읽기/쓰기 제한까지 포함해서 깊게 정리해보겠습니다.

반응형

댓글