- 제네릭스 (Generics)
- 제네릭스 타입과 표현식
- 제네릭스 사용법
제네릭스란 클래스나 메서드 내부에서 다룰 데이터의 클래스 타입을 지정하거나
컬렉션이 다룰 클래스 타입을 제한하여 한 가지 종류의 클래스만 저장할 수 있게 한 기능이다.
// 제네릭스 사용 X
List list = new ArrayList();
list.add("hello");
String str = (String)list.get(0);
// 제네릭스 사용 O
List<String> list = new ArrayList<String>();
list.add("hello");
String str = list.get(0);
타입을 파라미터 즉 매개변수로 가지는 클래스와 인터페이스 선언 시 클래스 또는 인터페이스 이름 뒤에 < >
를 붙이고 사이에는 타입 파라미터를 넣는다.
// 표현식
클래스명<클래스타입> 레퍼런스 = new 생성자<클래스타입>();
클래스명<클래스타입> 레퍼런스 = new 생성자<>();
// 사용 예시
ArrayList<Book> list1 = new ArrayList<Book>();
ArrayList<Book> list2 = new ArrayList<>();
ArrayList<Book> list = new ArrayList<Book>();
BookManager bm = new BookManager();
bm.printlnformation(list);
// BookManagaer Class
public void printformation(ArrayList<Book> list) {
}
메서드 쪽에서 받아주는 매개 변수도 제네릭스가 적용되어야 한다.
public ArrayList<Book> getInformation() {
ArrayList<Book> list = new ArrayList<Book>();
return list;
}
메서드의 반환형에도 제네릭스가 적용되어야 한다.
컴파일 시 타입 파라미터가 구체적인 클래스로 변경된다.
// 제네릭스 사용 클래스
public class Box<T> {
private T t;
public void set(T t) { this.t = t; }
public T get() { return t; }
}
// 구체적인 클래스로 변환
Box<Integer> box = new Box<Integer>();
box.set(6);
Integer i = box.get();
public class Box<Integer> {
private Integer t;
public void set(Integer t) { this.t = t; }
public Integer get() { return t; }
}
제네릭스 타입은 두 개 이상의 타입 파라미터 사용이 가능하며 콤마로 구분한다.
Employee<Dept, Person> = new Employee<Dept, Person>();
Employee<Dept, Person> = new Employee<>();
public class Employee<D, P> {
private D dept;
private D person;
public D getDept() { return this.dept; }
public P getPerson() { return this.person; }
public void setDept(D dept) { this.kind = kind; }
public void setPerson(P person) { this.person = person; }
}
제네릭스 타입을 부모 클래스로 사용해야 할 경우 타입 파라미터는 자식 클래스에도 기술한다.
public class ChildProduct<T, M> extends Product<T, M> { ... }
상속 및 구현 관계를 이용해 타입 제한이 가능하며 상위 타입은 클래스 뿐만 아니라 인터페이스도 가능하다.
<K extends T>
extends 를 사용하면 특정 타입의 자손 타입만 제네릭 타입으로 들어올 수 있다.
즉 T 와 T 의 자손 타입만 들어올 수 있다.
제네릭 타입에서는 클래스 뿐만 아니라 인터페이스도 extends 키워드를 사용한다.
<K super T>
super 을 사용하면 특정 타입의 부모 타입만 제네릭 타입으로 들어올 수 있다. 즉 T 와 T 의 부모 타입만 들어올 수 있다.
// 기본 사용
<?>
// 조합 사용
<? extends T>
<? super T>
물음표는 와일드 카드를 의미한다. 모든 타입이 제네릭 타입으로 들어올 수 있다.