출처 : 이것이자바다(한빛 미디어)
제네릭 타입을 이용함으로써 잘못된 타입이 사용 될 수 있는 문제를 컴파일링 과정에 제거할 수 있게 된다. 제네릭은 클래스와 인터페이스, 그리고 메소드를 정의할 때 타입을 파라미터로 사용할 수 있도록 한다.
자바 컴파일러는 코드에서 잘못 사용된 타입 때문에 발생하는 문제점을 제거하기 위해 제네릭 코드에 대해 강한 타입체크를 한다.
List list = new ArrayList();
list.add("hello");
String str = (String)list.get(0); // 제네릭을 사용하지 않을시 타입변환을 해야한다.
제네릭 타입은 타입을 파라미터로 가지는 클래스와 인터페이스를 말한다.
public class 클래스명<T> {}
public interface 인터페이스명<T> {}
제네릭 타입을 실제 코드에서 사용하려면 반드시 타입 파라미터에 구체적인 타입을 지정해야한다.
public class Apple{
public Object object;
public Object getApple(){
return object;
}
public void setApple(Object object){
this.object = object;
}
setApple(String str);
setApple(Long id);
setApple(Integer num);
}
자바 Object 클래스는 자바의 모든 클래스의 조상이기 때문에 모든 클래스의 인스턴스를 참조 할 수 있다. 즉 자료형이 무엇이든, 생성한 클래스의 인스턴스가 무엇이든 Object는 모든것을 다형성에 의해 참조할 수 있다.
public class Banana<T>{
public T t;
public void setT(T t){
this.t = t;
}
public T getT(){
return t;
}
}
모든 타입을 받을 수 있는 Object와는 다르게 제네릭은 한가지 자료형만을 참조할 수 있다.
public class Banana<String>{
public String string;
public void setT(String t){
this.t = t;
}
public String getT(){
return t;
}
public Integer num; // 제네릭 타입은 String이기 때문에 컴파일 에러 발생.
public Long getT(){
return t; // 컴파일 에러.
}
}
필드 타입을 명시해주고, String으로 변경 했을 경우 set()메서드는 String 타입만 매개값으로 받을 수 있게 변경되었다. get()메서드 역시 String 타입으로 리턴하도록 변경된다.
Banana<String> banana = new Banana<String>();
banana.setT("hello");
String t = banana.getT();
//타입 변환이 일어나지 않고, 컴파일에러가 발생하지 않는다.
Map<T,T>
Map<String,Integer> map = new HashMap<String,int>();
map.put("hello",1);
map.put("spring",2);
map.put("security",3);
Integer num1 = map.get("hello");
Integer num2 = map.get("spring");
Integer num3 = map.get("security");
// Generic 타입을 이용하여 Map에대한 타입을 고정할 수 있다.
map.put(1,10); // 컴파일 에러
map.put("hello","spring") // 컴파일 에러
제네릭 메서드는 매개 타입과 리턴타입으로 타입 파라미터를 갖는 메서드를 말한다.
제네릭 메서드를 선언 하는 방법은 리턴타입 앞에 <> 기호를 추가하고 타입 파라미터를 기술한 다음, 리턴타입과 매개 타입으로 타입 파라미터를 사용하면 된다.
pulic <T> String<T> get(T t){}