Java

지네릭스 제약네릭스 제약

1space 2025. 6. 25. 23:41

자바의 정석[기초편]으로 공부한 내용을 정리한 글입니다.

제한된 지네릭 클래스

요점:
<T extends Fruit>처럼 extends를 써서 타입 변수에 들어올 수 있는 타입을 제한할 수 있습니다.

예제

class FruitBox<T extends Fruit> {
    ArrayList<T> list = new ArrayList<T>();
    ...
}
  • FruitBox는 Fruit 또는 그 자손 클래스만 T로 받을 수 있습니다.
  • 예를 들어 FruitBox<Apple>은 OK (Apple이 Fruit의 자손).
  • FruitBox<Toy>는 에러 → Toy는 Fruit을 상속받지 않았기 때문.
interface Eatable { ... }

class FruitBox<T extends Eatable> { ... }
  • 인터페이스일 경우에도 extends를 사용합니다. (자바에서는 클래스나 인터페이스 모두 extends로 제한)
  • implements는 실제 구현할 때 쓰는 키워드이고, 타입 제한에서는 extends로 통일됩니다.

 

지네릭스의 제약

지네릭은 강력하지만 몇 가지 제약 사항이 존재합니다.

1. 타입 변수는 인스턴스마다 다르게 설정 가능

Box<Apple> appleBox = new Box<Apple>();
Box<Grape> grapeBox = new Box<Grape>();
  • Box는 하나의 클래스지만, Apple과 Grape라는 다른 타입 변수로 여러 객체 생성 가능.
  • 즉, Box<T>의 T는 인스턴스마다 다를 수 있음.

2. static 멤버에 타입 변수 사용 불가

class Box<T> {
    static T item;         // ❌ 에러
    static int compare(T t1, T t2) { ... }  // ❌ 에러
}
  • static 변수나 static 메서드는 클래스 로딩 시점에 메모리에 올라가야 합니다.
  • 그런데 타입 변수 T는 인스턴스를 생성할 때 결정되므로, static에는 사용할 수 없습니다.

3. 타입 변수로 배열 생성은 불가

T[] itemArr;           // ✅ 선언은 가능
T[] tmpArr = new T[];  // ❌ new T[길이]는 에러
  • 배열을 선언만 하는 건 가능 (T[] itemArr)
  • 하지만 new T[]처럼 직접 배열 생성은 불가능 → 타입이 컴파일 시점에 결정되지 않기 때문
  • 해결 방법: Object[]로 생성하거나, Array.newInstance() 사용 등

 

'Java' 카테고리의 다른 글

열거형(enum)  (0) 2025.06.26
와일드 카드, 지네릭 메서드  (0) 2025.06.26
Iterator, HashMap과 지네릭스  (0) 2025.06.25
지네릭 다형성  (0) 2025.06.25
타입 변수  (0) 2025.06.25