[JAVA] Generics

손호영·2023년 11월 7일
post-thumbnail

지네릭스란?

  • 다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스에 컴파일 시의 타입체크를 해주는 기능이다.
  • 객체의 타입을 컴파일 시에 체크하기 때문에 객체의 타입 안정성을 높이고 형변환의 번거로움이 줄어든다.

지네릭 클래스의 선언

클래스 옆에 < T > 를 붙이면 지네릭 클래스가 됨.

class Box<T>{
	T item;
    void setItem(T item) {this.item = item;}
    T getItem();
}

이 의미는 만약 아래와 같이 사용하게 된다면,

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

T 타입을 String 으로 지정해 줬으므로

class Box{
	String item;
    void setItem(String item) {this.item = item;}
    String getItem();
}

이와 같이 정의된 것으로 됨.

지네릭스의 제한

  • static멤버에 타입 변수 T를 사용할 수 없음.
  • 지네릭 타입의 배열을 생성하는 것도 허용되지 않음. (new T[10] 이런게 안된다는 것.)
    • new 연산자 때문인데, 이 연산자는 컴파일 시점에 타입 T가 뭔지 정확히 알아야 된다.
    • 꼭 지네릭 배열을 생성해야 하면 Reflection API의 newInstance()를 사용

제한된 지네릭 클래스

class FruitBox<T extends Fruit> {
	ArrayList<T> list = new ArrayList<T>();
    ...
}

다음과 같이 지네릭 타입에 'extends' 를 사용하면, 특정 타입의 자손들만 대입할 수 있게 제한할 수 있음

만일 클래스가 아니라 인터페이스를 구현해야 한다는 제약이 필요하다면 마찬가지로 'extends' 사용

클래스의 자손이면서 인터페이스도 구현해야 한다면 아래와 같이 '&' 기호로 사용

class FruitBox<T extends Fruit & Eatable> {...}

와일드 카드

와일드 카드는 어떠한 타입도 될 수 있고, '?'로 표현함.

< ? extends T > 와일드 카드의 상한 제한. T와 그 자손들만 가능
< ? super T > 와일드 카드의 하한 제한. T와 그 조상들만 가능
< ? > 제한 없음. 모든 타입이 가능

이를 이용하면 지네릭 클래스가 아닌 클래스의 스태틱 메서드에 지네릭 타입의 클래스를 선언이 가능하게 됨.

지네릭 메서드

메서드의 선언부에 지네릭 타입이 선언된 메서드를 지네릭 메서드라고 함.

static <T> void sort(List<T> list, <Comparator<? super T> c)

static 멤버에는 타입 매개변수를 사용할 수 없지만, 위와 같이 static 메서드에 지네릭 타입을 선언하고 사용하는 것은 가능.

지네릭 타입의 제거

컴파일러는 지네릭 타입을 이용해 소스파일을 체크하고 필요한 곳에 형변환을 넣어줌. 그리고 지네릭 타입을 제거.

즉 컴파일 된 파일에는 지네릭 타입에 대한 정보가 없음

참고 : <Java의 정석>

profile
안녕하세요. 열심히 해보겠습니다

0개의 댓글