[Java] 제네릭 만들기
2021. 12. 13. 15:52ㆍLanguage`/Java
제네릭 클래스 작성
- ex) 타입 매개변수 T를 가진 제네릭 클래스 Myclass
- ex) 타입 매개변수 T를 가진 제네릭 클래스 stack (스택 자료구조)
class Myclass<T>{
T val; // 타입이 T인 변수 val
void set(T val){
this.val = val;
}
T get(){ // 값 val를 타입 T로 return
return val;
}
}
class stack<T>{
int top; // 스택의 top
Object [] stack; // item을 저장할 stack 배열
public stack(){
top = -1;
stack = new Object[10];
// 제네릭 매개변수로는 객체 생성, 배열 생성이 불가능
// 따라서 Object 배열을 생성해서 실제 타입 객체를 item으로 push
}
public void push(T item){
if(top == 9)
return;
else
stack[++top] = item;
}
public T pop(){
if(top == -1)
return null;
return (T)stack[top--];
// Object 배열로 생성했기 때문에 타입 매개변수 타입으로 강제 캐스팅이 필수
}
}
타입 매개변수
- 제네릭 클래스 내에서 제네릭 타입을 가진 객체의 생성은 허용되지 않는다
- 제네릭 매개변수로 객체 생성, 배열 생성 등을 할 수 없다
- 배열을 생성하려면 Object의 배열로 생성하고, 타입 매개변수 타입으로 강제 캐스팅을 해야 한다
public stack(){
top = -1;
stack = new Object[10];
// 제네릭 매개변수로는 객체 생성, 배열 생성이 불가능
// 따라서 Object 배열을 생성해서 실제 타입 객체를 item으로 push
}
public T pop(){
if(top == -1)
return null;
return (T)stack[top--];
// Object 배열로 생성했기 때문에 타입 매개변수 타입으로 강제 캐스팅이 필수
}
- Object의 배열로 생성 -> 배열의 요소를 return 할 때 타입 매개변수 타입으로 강제 캐스팅
제네릭 메소드
- 타입 매개변수는 메소드의 리턴 타입 앞에 선언
public static <T> stack<T> reverse(stack<T> a){
// 리턴타입 = stack<T>, 타입 매개변수 = <T>
stack<T> s = new stack<T>(); // 스택 a를 반대로 저장하는 스택 s
while(true){
T tmp; // 교환 변수
tmp = a.pop();
if(tmp==null)
break;
else
s.push(tmp);
}
return s;
}
제네릭 장점
- 동적으로 타입이 결정되지 않고, 컴파일 시에 타입이 결정되어서 안전한 프로그래밍 가능
- 런타임 타입 충돌 문제 방지
- 개발 시 타입 캐스팅 절차 불필요
- ClassCastException 방지