[Java] Generics

얄루얄루·2022년 9월 18일
0

Java

목록 보기
6/7

제네릭 클래스

간단히 말해서 하나의 클래스로 여러가지 자료형을 다 이용할 수 있게 하는 형식의 클래스이다.

Java를 조금 써 봤다면

HashSet<Integer> 같은 자료형을 다뤄 봤을텐데, 이 HashSet클래스를 타고 가 보면 Integer는 온데 간데 없고 HashSet<E>라고 떡 하니 클래스 선언이 되어 있는데, 이게 바로 제네릭 클래스로 선언이 된 것이다.

제네릭 클래스를 사용하면

  • 형변환의 번거로움을 줄이고, 미리 컴파일 시 체크함으로써 안정성이 향상된다
  • 형태와 기능이 완전히 같고 다루는 자료형만 다른 클래스를 여러 개 만들지 않아도 된다

와 같은 이점이 있다.

public class Box<T> {
    private T t;

    public void set(T t) { this.t = t; }
    public T get() { return t; }
}
public interface Pair<K, V> {
    public K getKey();
    public V getValue();
}

public class OrderedPair<K, V> implements Pair<K, V> {

    private K key;
    private V value;

    public OrderedPair(K key, V value) {
	this.key = key;
	this.value = value;
    }

    public K getKey()	{ return key; }
    public V getValue() { return value; }
}

제네릭 메소드

제네릭 클래스와 다를 거 하나 없지만, 제네릭 변수의 범위가 해당 메소드로 한정된다는 것만이 다르다.

그런데, 클래스 내 필드값이 특정 자료형으로 고정이 되어 있다면 이걸 굳이 제네릭 메소드를 이용해 처리 할 필요는 없기 때문에 사실상 static 메소드에서 많이 활용한다.

static <T> void fromArrayToCollection(T[] a, Collection<T> c) {
    for (T o : a) {
        c.add(o);
    }
}

제네릭 문자

E, T, K, V 등등이 있는데, 정해진 규칙 따윈 없고 전부 convention에 불과하다.

다 마음에 안 들면 Z로 해도 되고, L로 해도 된다.

다만 convention을 지키는 데에서 오는 이점도 있으니, 지킬 수 있다면 지키는 편이 좋겠다.

  • T – Type
  • E – Element (Collection 내에서 주로 쓴다)
  • K – Key
  • V – Value
  • N – Number
  • S, U etc.

등이 관련된 문자이다.

제네릭 제한

제네릭 타입에 extends/super 키워드를 사용하면 그 클래스와 그 클래스를 상속받는 자식클래스들만 이용 가능하게 할 수 있다.

<? extends T> 상한 제한 (upper bound): T와 그 자손들의 인스턴스만 매개변수로 가능
<? super T> 하한 제한 (lower bound) : T와 그 부모들의 인스턴스만 매개변수로 가능

interface Collection<E> {
    public <T extends E> boolean addAll(Collection<T> c);
}

와일드 카드

보통 제네릭 제한에 이용된다.

바로 위의 코드를 보면 저기서 사실 T는 아무 의미가 없다. 클래스는 E형으로 만들어 질 것이고, T는 E를 상속한 어떤 클래스라는 것인데 그냥 자리 메우기용 밖에는 되지 않는다.

이런 경우에 와일드 카드인 ?를 사용할 수 있다.

interface Collection<E> {
    public <E> boolean addAll(Collection<? extends E> c);
}
static List<List<? extends Shape>> 
    history = new ArrayList<List<? extends Shape>>();

public void drawAll(List<? extends Shape> shapes) {
    history.addLast(shapes);
    for (Shape s: shapes) {
        s.draw(this);
    }
}
profile
시간아 늘어라 하루 48시간으로!

0개의 댓글

관련 채용 정보