클래스나 메소드에서 사용할 내부 데이터 타입을 외부에서 지정하는 기법
제네릭이란?
// 지네릭 사용x
class Box {
Object item;
void setItem(Object item) { this.item = item; }
Object getItem() { return item; }
}
// 지네릭 사용
class Box<T> { // 지네릭 타입 T 선언
T item;
void setItem(T item) { this.item = item; }
T getItem() { return item; }
}
컴파일 단계에서 자료형을 체크해주는 도구
실행시 타입 에러가 나는 것보다 컴파일시에 미리 강하게 타입을 체크하여 에러를 사전에 방지함
타입변환을 제거할 수 있어서 시스템 오버헤드를 줄일 수 있음
예시)
List list = new ArrayList(); // List 인터페이스 타입에 ArrayList() 클래스 객체 생성
// list에 모든 객체를 다 담을 수 있음(object 타입)
list.add("hello"); // string으로 입력했지만 형변환 돼서 list에는 object 타입으로 저장됨
String str = (String) list.get(0); // object 타입을 string 형변환해야 값을 얻을 수 있음
// 제네릭 사용시
List<String> list = new ArrayList<String>();
// List와 ArrayList에 string만 저장한다고 선언
list.add("hello"); // string으로 저장됨
String str = list.get(0); // 형변환 필요없음
타입을 명시해줘서 코드 가독성이 높아짐
[ 리빙포인트 ]
컴파일 때까지만 제너릭 타입을 체크하고 런타임에는 제너릭 타입을 삭제함( 런타임 때는 제너릭 타입 정보가 없음 )
왜냐면, 자바 하위 버전에는 제네릭 타입을 체크하지 않으
타입을 피라미터로 가지는 클래스와 인터페이스를 뜻함
public class 클래스명<T> { ... }
public interface 인터페이스명<T> { ... }
예시)
public class Box<T> {
private T t;
public T get() { return t; }
public void set(T t) { this.t = t; }
// Box<T> 객체 생성하는 경우
Box<String> strBox = new Box<String>();
Box<Integer> intBox = new Box<Integer>();