자바 제너릭 Generic
아래 예시를 보며 generic이 왜 필요한지 느껴보자 feel it
Human class
public class Human{
private Object height;
public void setHeight(Object height){
this.height = height;
}
public Object getHeight(){
return height;
}
}
1. Object라는 클래스형의 height라는 필드를 생성
2. height에는 값 할당 가능
3. get 메소드(getHeight) 는 값을 꺼내는 것이기에 리턴 타입 필요 -> public Object getHeight()
Main method
public class Humanbeing {
public static void main(String args[]){
Human hoo = new Human();
hoo.setHeight("tall")
String strHeight = (String)hoo.getHeight();
hoo.setHeight(200)
int intHeight = (int)hoo.getHeight();
}
}
hoo 인스턴스는 Object 클래스형.
hoo.setHeight(여기 인자부분에는) Object 클래스를 상속받는 클래스(int, String, etc)는 모두 올 수 있다.
"tall" 값은 할당 받을 때, hoo.getHeight()는 String 형으로 형변환을 거쳐야 한다
(원래 getHeight()메소드는 Object형이였으므로)
=> (String)hoo.getHeight();
마찬가지로, 200 이라는 숫자 값을 할당 받을 때는 int형으로 형변환을 거쳐야 한다.
=> (int)hoo.getHeight();
문제점
get 메소드를 호출할 때마다 형 변환을 거치는 것은 비효율적
해결책
- Generic 등장✨ (since Java 8)
- 일일이 형변환 하는 과정을 생략하도록, 처음 객체를 생성할 때 클래스형을 지정 .
- 화살괄호 <> 안에 사용하고자 하는 클래스형을 작성.
public class Human<E>{
private E height;
public void setHeight(E height){
this.height = height;
}
public E getHeight(){
return height;
}
}
1. 기존 Human 클래스의 Object (형)을 모두 E로 치환 (E는 가상의 클래스)
2. setHeight(E height)에선, 가상의 클래스형(E)인 height를 인자로 넘기고
3. getHeight()에선, 가상의 클래스형(E)의 리턴타입 기재.
public class Humanbeing {
public static void main(String args[]){
Human<String> hoo = new Human();
hoo.setHeight("tall")
String strHeight = hoo.getHeight();
Human<int> hoo = new Human();
hoo.setHeight(200)
int intHeight = hoo.getHeight();
}
}
1. 인스턴스를 만들 때, 미리 클래스형(String, int, etc)을 화살괄호 안에 선언
2. 별도의 형 변환 과정 불필요
결론
generic을 사용하면,
1) 클래스를 선언할 때는 가상의 타입으로 선언
2) 사용시에는(main method에서) 구체적 타입을 설정함(<String>, <int>, etc)으로 다양한 타입의 클래스를 이용 가능