제네릭 정리
제네릭
프로그램의 안정성을 도와주면서 컴파일 단계에서 자료형을 체크해주는 도구 입니다.
아래의 코드를 통해 제네릭에 대해 알아 보겠습니다.
Chicken.class, ChickenBox.class
class Chicken {
}
class ChickenBox {
private Chicken[] box = new Chicken[10]; // Chicken클래스만 넣을수 있는 box
int cursor = 0;
void putData(Chicken chicken) {
box[cursor++] = chicken; // Chicken 클래스를 담는 putData
}
Chicken getData() {
Chicken chicken = box[cursor -1];
box[cursor - 1] = null;
cursor--;
return chicken; // box에서 Chicken클래스를 리턴 받음
}
}
Book.class, BookBox.class
class Book {
}
class BookBox {
private Book[] box = new Book[10]; // Book클래스만 넣을수 있는 배열 box
int cursor = 0;
void putData(Book book) {
box[cursor++] = book; // Book클래스를 담는 putData
}
Book getData() {
Book book = box[cursor -1];
box[cursor - 1] = null;
cursor--;
return book; // box에서 Book클래스를 리턴 받음
}
}
ChickenBox나 BookBox는 로직상 차이가 없는 무엇인가 담는 박스일 뿐입니다.
매번 Box 클래스를 만들려면 똑같은 클래스를 또 만들어야 하는가?
매번 같은 클래스를 만들 필요 없이 최상위 클래스인 Object 클래스를 사용하면 됩니다.
아래는 Object 클래스를 사용하여 만든 Box 클래스 입니다.
Box.class
class Box {
private Object[] box = new Object[10];
int cursor = 0;
void putData(Object book) { // putData에 파라미터 자료형이 Object이기 때문에 아무 클래스 대입 가능. 여기가 문제
box[cursor++] = book;
}
Object getData() {
Object book = box[cursor -1];
box[cursor - 1] = null;
cursor--;
return book;
}
}
위의 Box 클래스에 putData로 원하는 클래스를 넣을수 있지만 여기서 문제가 발생합니다.
Box chickenBox = new Box();
chickenBox.putData(new Chicken());
Chicken chicken1 = (Chicken)chickenBox.getData();
chickenBox.putData(new Book()); // putData()파라미터가 Object이기 때문에 Chicken클래스가 아닌 Book도 가능
Chicken chicken2 = (Chicken)chickenBox.getData(); // 프로그램 시행 도중 형변환 에러 발생
코드 작성자 의도 되로 사용되지 않고 위처럼 문제가 발생할 우려가 있습니다. 또한 프로그램 실행시 에러가 나기 때문에
코드 작성시에는 발견이 쉽지 않습니다.
이런 경우에 제네릭을 사용하여 해결 할 수 있습니다.
제네릭을 사용하여 아래에 코드를 짜보겠습니다.
class Box <T> {
private Object[] box = new Object[10];
int cursor = 0;
void putData(T book) {
box[cursor++] = book;
}
T getData() {
T book = (T)box[cursor -1];
box[cursor - 1] = null;
cursor--;
return book;
}
}
제네릭은 Formal type parameter 선언하고 사용하여 제네릭 클래스를 만들수 있습니다. 제네릭은 모든 타입을 받을 수 있는 Object와 유사 하나 Formal type을 지정함으로써 타입이 관련된것으로만 한정되는 제약이 있어 Object를 사용한 클래스와는 차이가 있습니다.
즉 T가 Chicken으로 정해지면 모든 T들이 Chicken으로 지정됩니다. 그렇기때문에 안정된 코드를 만들 수 있습니다.
모습은 아래와 같습니다.
Box<Chicken> chickenBox = new Box<>();
chickenBox.putData(new Chicken());
Box<Book> bookBox = new Box<>();
bookBox.putData(new Book());
Chicken chicken1 = chickenBox.getData(); // 명시적인 형변환이 필요없음
출처