[Java] Generic class
★Generic class : 다루는 클래스를 정해놓지 않고 사용하는 클래스, 컴파일 시에 클래스가 확정된다.
★기본적인 제네릭 클래스 선언
class Box<T> {
T t;
public void (T t) {
this.t = t;
}
public T getT() {
return t;
}
}
...
public void doSomething() {
Box<String> box = new Box<String>();
bos.setT("헬로");
String t = box.getT();
// Box안에 String이외의 다른 타입을 넣으면 컴파일 에러가 발생한다.
// 꺼내 쓸때 캐스팅이 따로 필요없음
}
★꺽쇠<>
안에 들어가는 타입을 타입 매개변수라고 한다. 컴파일시 이 타입 매개변수는 타입 소거자(Type Erasure)에 의해 삭제된다. 그래서 위의 Box<String> box = new Box<String>();
는 컴파일 후에는 Box box = new Box();
로 바뀐다.
★타입 파라메터 네이밍
E : 엘레멘트
K : 키
N : 숫자
T : 타입
V : 값
S,U,V… : 두번째, 세번째, 네번째 타입…
★Generic Method : 클래스 단위가 아니더라도 메소드수준에서도 사용할 수 있다.
public <U> void printBox<U info> {
System.out.println(info)
}
함수 호출에 대헤 어떤 타입인지 선언 안해도 잘 작동한다. 컴파일러가 printBox에 String이 들어온것을 알기 때문에 U=String인것을 추론하기 때문. 이런 기능을 타입 추론(Type Inference)라 한다. 타입 추론을 통해 생성자에서도 생략이 가능하다.
Box<Integer> box = new Box<Integer>(1);
//위와 아래는 동일한 코드
Box box = new Box(1);
★
★Generic클래스에서 어떤 타입을 사용할지 아직 정확히 안 정해진 경우 Wildcard라는 것을 사용할 수 있다. 즉 어떤 타입이든 관계없이 해당 클래스의 메소드를 사용하고 싶을 때 ?
를 타입으로 사용한다.
public int count (Set<?> s1, Set<?> s2) {
...
}
이러한 사용법을 비 한정적 와일드카드 자료형
이라고 한다.
★한정적 와일드카드 자료형 : 파라메터 클래스타입을 제한하려면 와일드카드와 extends키워드를 같이 사용한다.
- extends : 어떤 클래스의 서브클래스여야 한다는 의미
- super : 어떤 클래스의 조상클래스여야 한다는 의미
★보통 쓰기를 할 때는 extends, 읽기를 할 떄는 super를 사용하며 둘 다 할때는 wildcard를 안쓴다고한다.
★제네릭 클래스는 배열을 생성할 수 없다.
// error code
private T[] table = new T[10];
private Entry<K, V>[] table = new Entry<K, V>[10];
★위 두 코드는 실행되지 않는다. 컴파일러가 컴파일을 수행할 때 type parameter인 T, K, V가 실제로 나타내는 타입을 알 수 없기 때문이다. 무슨 말이냐면 배열 생성 구문에 타입 파라메터를 써 주더라도 컴파일 타임에 타입 파라메터 정보는 사라지기 때문에 런타임에 그 정보를 사용할 수 없다. 그래서 런타임에 배열을 생성할 수 없는 것이다. 단 형변환은 가능하기 때문에 아래와 같은 트릭을 사용한다.
private T[] table = (T[])new Object[10];
private Entry<K, V>[] table = (Entry<K, V>[])new Entry[capacity];
★첫 번째 코드는 T가 어떤 타입이든 기본적으로 Object타입이 된다. 그래서 모든 자식 클래스로 형변환이 가능하기 때문이고, 두 번째 케이스는 컴파일하면 new Entry[]
의 모양이 되고 새 Entry배열속의 Entry의 Type paramenter인 K와 V는 Object타입으로 되어있다. 따라서 이를 <K, V>로 형변환 해 준 것이다. 아 말이 어렵노.
★참고로 이렇게 컴파일 타임에 타입 파라메터가 사라지는 타입을 비 구체화 타입
이라고 하고, 그 반대를 구체화 타입
이라고 한다.