[생활코딩]제네릭
StudentInfo<T> si = new StudentInfo<T>();
=> StudentInfo<String> si = new StudentInfo<String>();
=> StudentInfo<Integer> si = new StudentInfo<Integer>();
제네릭은 사용하는 이유 : 어떤 클래스 내의 변수의 타입을 유연하게 하기 위해 Object으로 지정하면 특정한 데이터타입의 집합으로 한정지을 수가 없다. 이렇게 될 경우, type safety가 만족되지 못한다. (사용자의 실수로 클래스가 원하지 않는 데이터타입을 입력해도 컴파일단계에서는 에러가 생기지 않고 런타임에러로 생긴다. 컴파일 단계에서 이러한 실수를 잡기 위해 Generic을 사용한다.) 제네릭은 그 자체는 어떤 데이터타입도 올 수 있지만 코딩단계에서 데이터타입을 명시한다. (?)
class EmployeeInfo{
public int rank;
EmployeeInfo(int rank) {
this.rank = rank;
}
}
class Person<T, S>{ //제네릭의 데이터타입은 기본 데이터타입은 에러가 발생한다. Wrapper클래스를 대신 사용한다.
public T info;
public S id;
Person(T info, S id){
this.info = info;
this.id = id;
}
public <U> void printInfo(U info){
System.out.println(info);
}
}
public class GenericDemo{
public static void main(String[] args){
1)
Integer id = new Integer(1); //wrapper 클래스로 감싼다.
Person<EmployeeInfo, Integer> p1 = new Person<EmployeeInfo, Integer>(new EmployeeInfo(1), id);
System.out.println(p1.id.intValue()); //다시 int형으로 가져온다.
---------------------------------------------------------------------
2) 데이터타입 명시 생략가능
EmployeeInfo e = new EmployeeInfo(1);
Integer i = new Integer(10);
Person p1 = new Person(e, i);
//p1.<EmployeeInfo>printlnfo(e);
p1.printlnfo(e);
}
}
-----------------------------------------------------------------------------------------------------------
3) T의 부모 클래스(상속 혹은 구현한 클래스)를 제한
interface
Info{
int
getLevel();
}
class
EmployeeInfo
implements
Info{
public
int
rank;
EmployeeInfo(
int
rank){
this
.rank = rank; }
public
int
getLevel(){
return
this
.rank;
}
}
class
Person<T
extends
Info>{
public
T info;
Person(T info){
this
.info = info; }
}
public
class
GenericDemo {
public
static
void
main(String[] args) {
Person p1 =
new
Person(
new
EmployeeInfo(
1
));
Person<String> p2 =
new
Person<String>(
"부장"
);
}
}