제네릭스는 다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스에 컴파일 시의 타입체크를 해주는 기능이다.
따라서 객체의 타입을 컴파일 시에 테크하기 때문에 객체의 타입 안정성을 높이고 형변환(castion)의 번거로움이 줄어든다.
예를 들어, ArrayList와 같은 컬렉션 클래스는 다양한 종류의 객체를 담을 수 있긴하지만 보통 한 종류의 객체를 담는 경우가 더 많다. 그런데도 꺼낵 때 마다 타입체크를 하고 형변환을 하는 것은 아무래도 불편할 수밖에 없다. 게다가 원하지 않는 종류의 객체가 포함되는 것을 막을 방버이 없다는 것도 문제다. 이러한 문제들을 제네릭스가 해결해준다.
출처 : 자바의 정석 3rd Edtion 2권 p.670.
→ 제네릭 프로그래밍과 연결됨.
public class Box {
Object item;
void setitem(Object item) {
this.item = item;
}
public Object getitem() {
return item;
}
}
class Box<T> { // T는 타입을 의미한다.
T item;
void setItem(T item) {
this.item = item;
}
public T getItem() {
return item;
}
}
box<T'>에서 T를 타입변수라고 하며 Type의 첫 글자에서 따온 것이다.
타입변수는 T가 아닌 다른 것을 사용해도 된다.
ArrayList<E'>의 경우 타입변수 E는 Element의 첫 글자를 따서 사용했다. 타입변수가 여러개인 경우에는 Map<K,V>와 같이 콤마를 구분자로 나열하면 된다.
K는 Key를 의미하고, V는 Value를 의미한다.
무조건 T를 사용하기보다는 가능하면 이처럼 상황에 맞게 의미있는 문자를 선택해서 사용하는 것이 좋다.
따라서 이들은 기호의 종류만 다를 뿐 임의의 참조형 타입을 의미한다는 것은 모두 같다
이제 지네릭 클래스가 된 Box클래스의 객체를 생성할 때는 다음과 같이 참조변수와 생성자에 타입 T대신에 사용될 실제 타입을 지정해주어야 한다.
Box<String> b = new Box<String>(); // 타입 T 대신 실제 타입을 지정. String 타입만 저장.
b.setItem(new Object()); //에러. String 이외의 타입은 지정 불가
b.setItem("ABC"); // ok. String타입이므로 가능
String item = b.getItem() // 형변환이 필요없다.
참고 : 출처 : 자바의 정석 3rd Edtion 2권 p.671.
E – Element(요소 : 자바 컬렉션 라이브러리에서 많이 사용된다.)
K – Key
N – Number
T – Type
V – Value
S, U, V 등 – 2번째, 3번째, 4번째 타입
이번 Spring 기본주차 과제를 하던중 ResponseEntity를 이용해서 repsonse header에 직접적으로 메시지를 보내야 할 부준이 있어서 CS스터디 할때 팀원분들과 얘기하던 도중 제네릭스가 나와서 긴가민가 하던 중에 오래전 책장에 꽂아두고 있던 자바의 정석을 다시 꺼내서 공부했다.
나는 여기서 내가 자바를 어떻게 공부하고 있었는지 다시금 반성했지만 반면에 처음 자바를 공부했을때가 떠올라 아 내가 이거를 공부하는 수준까지 온건가라고 조금 놀랬다. 이부분은 처음에 이해가 도저히 안되서 무서워서 넘어갔던게 기억났기 때문이다.
결국 건너뛰었던 혹은 막혔던 부분은 언젠가 마주친다는 것이 사실이었다..