[Java] 제네릭(Generic)

2025. 1. 21. 13:43·프로그래밍 언어/Java

제네릭(Generic)이란?

"결정되지 않은 타입을 파라미터로 처리하고 실제 사용할 때 파라미터를 구체적인 타입으로 대체시키는 기능

public class Box <T> {
	pulic T content;
}
  • Box클래스에서 결정되지 않은 content의 타입을 T라는 타입 파라미터로 정의한 것.
  • <T>는 T가 타입 파라미터임을 뜻하는 기호로, 타입이 필요한 자리에 T를 사용할 수 있음을 알려주는 역할
Box<String> box = new Box<String>();
box.content = "문자열예시";

Box<Integer> box = new Box<>(); //생성자 호출시 생성자 타입 생략 가능
  • 이때 기본 타입은 타입 파라미터의 대체 타입이 될 수 없음 -> int, double, char와 같은 기본형 타입 사용 불가능
  • 반드시 Wrapper 클래스(Integer, Double, Character) 사용
    • Why? - 타입 소거(Type Erasure)
    • 제네릭은 컴파일 타임에만 타입을 체크하고, 런타임에는 타입 정보가 소거되기 때문

 

제네릭 타입

  • 결정되지 않은 타입을 파라미터로 가지는 클래스와 인터페이스
public class 클래스명<A, B, >{ }
pulic interface 인터페이스명<A, B, >{ }
  • 외부에서 제네릭 탕비을 사용하려면 타입 파라미터에 구체적인 타입을 지정해야 함
  • 지정하지 않으면 Object타입이 암묵적으로 사용됨

 

  • Product 클래스를 제네릭 타입으로 생성
public class Product<K, M>{
	//필드
    private K kind;
    private M model;

	//메소드
    public K getKind(){ return this.kind;}
    public M getModel(){ return this.model;}
    public void setKind(K kind){ this.kind = kind;}
    public void setModel(M model){ this.model = model;}
}
public class Tv{}
  • Product 제네릭 타입을 이용해 Tv 정보를 저장하고 얻는 방법
public class GenericEX{
	public static void main(String[] args){
    	
        Product<Tv, String> product1 = new Product<>();
        product1.setKind(new Tv());
        product1.setModel("스마트 tv");
        
        Tv tv = product1.getKind();
        String tvModel = product1.getModel();
   }
}

 

제네릭 메소드

  • 타입 파라미터를 가지고 있는 메소드
  • 타입 파라미터가 메소드 선언부에 정의된다는 점에서 제네릭 타입과 차이가 있음
public <A, B> 리턴타입 메소드명(매개변수){ }

//예시
public class Box<T>{
	private T t;
}

public class EX{
	public static <T> Box<T> boxing(T t){
    	Box<T> box = new Box<T>();
        return box;
    }
}

 

 

제한된 타입 파라미터

  • 경우에 따라 타입 파라미터를 대체하는 구체적인 타입을 제한할 필요가 있음
  • 예를 들어 숫자 연산하는 제네릭 메소드는 대체 타입으로 Number 또는 자식 클래스로 제한할 필요가 있음
  • 이처럼 모든 타입으로 대체할 수 없고 특정 타입과 자식 또는 구현 관계에 있는 타입에만 대체할 수 있는 타입 파라미터를 제한된 타입 파라미터라고 함
public <T extends 상위타입> 리턴타입 메소드명(매개변수){ }

//예시
public <T extends Number> boolean compare(T t1, T t2){
	double v1 = t1.doubleValue();
    double v2 = t2.doubleValue();
    return (v1 == v2);
}

 

 

와일드카드 타입 파라미터

  • 제네릭 타입을 매개값이나 리턴 타입으로 사용할 때 타입 파라미터로 ?(와일드 카드)를 사용할 수 있음
  • ?는 범위에 있는 모든 타입으로 대체할 수 있다는 표시

 

  • 일반 와일드카드
public void printList(List<?> list) {
    for (Object obj : list) {
        System.out.println(obj);
    }
}
  • Upper Bounded Wildcard
    • ? extends Type는 타입이 특정 클래스 또는 그 하위 클래스임을 나타냄
public double sumList(List<? extends Number> list) {
    double sum = 0.0;
    for (Number num : list) {
        sum += num.doubleValue();
    }
    return sum;
}
  • Lower Bounded Wildcard
    • ? super Type는 타입이 특정 클래스 또는 그 상위 클래스임을 나타냄
public void addNumber(List<? super Integer> list) {
    list.add(10); // Integer 또는 그 상위 타입에 값을 추가할 수 있음
}

 

 

제네릭의 한계

  • 런타임 타입 소거(Type Erasure)
    • 제네릭은 컴파일 타임에만 존재하며, 런타임 시에는 소거됨
    • 따라서 런타임에 제네릭 타입 정보는 알 수 없음
public static void printType(List<String> list) {
    if (list instanceof List<String>) {  // 컴파일 오류
        // 불가능
    }
}
  • Primitive 타입 사용 불가
    • 제네릭은 레퍼런스 타입만 지원하므로 기본형 타입은 사용할 수 없음
    • 대신 Wrapper 클래스(예: Integer, Double)를 사용
List<int> list = new ArrayList<>(); // 오류
  • 정적 컨텍스트에서 사용 제한
    • 정적 변수나 정적 메서드에서 타입 파라미터를 사용할 수 없음
public class MyClass<T> {
    private static T value; // 오류
}

'프로그래밍 언어 > Java' 카테고리의 다른 글

[Java] 컬렉션 자료구조  (1) 2025.02.04
[Java] 멀티 스레드  (1) 2025.01.23
'프로그래밍 언어/Java' 카테고리의 다른 글
  • [Java] 컬렉션 자료구조
  • [Java] 멀티 스레드
Jaemin0604
Jaemin0604
정재민님의 블로그 입니다.
  • Jaemin0604
    정재민님의 블로그
    Jaemin0604
  • 전체
    오늘
    어제
    • 분류 전체보기 (23)
      • 알고리즘 (9)
      • 자료구조 (3)
      • 코딩테스트 (1)
        • 백준 (1)
        • 프로그래머스 (0)
      • CS공부 (7)
        • 운영체제 (2)
        • 네트워크 (2)
        • 데이터베이스 (2)
        • 자료구조 (1)
        • 알고리즘 (0)
      • 프로그래밍 언어 (3)
        • Java (3)
        • Swift (0)
      • 백엔드 개발 (0)
  • 블로그 메뉴

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

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Jaemin0604
[Java] 제네릭(Generic)
상단으로

티스토리툴바