제네릭의 표현 방식
class Box<T>{...}
Box<Apple> abox = new Box<Apple>();
Box<Orange> oBox = new Box<Orange>();
1. 타입 매개변수 : Box<T>에서 T
2. 타입 인자 : Box<Apple> 에서 [Apple], Box<Orange> 에서 [Orange]
3. 매개변수화 타입 : Box<Apple>, Box<Orange>
타입 매개변수의 이름은 짓기 나름이다. 일반적으로 두 가지 규칙을 지켜서 이름을 짓는다
- 한 문자로만 이름을 짓는다
- 대문자로만 이름을 짓는다
대표적인 5가지 매개변수
- E : Element
- K : Key
- N : Number
- T : Type
- V : Value
제네릭은 클래스 전부가 아닌 일부 메소드에 대해서만 제네릭으로 정의하는 것이 가능하며, 이렇게 정의된 메소드를 가리켜'제네릭 메소드'라 한다.
public static<T> Box<T> makeBox(T o){...}
"메소드의 이름은 makeBox이고 반환형은 Box<T>이다."
이후로도 위와 같은 메소드 정의를 보면 Box<'T'>가 반황형임을, 그 앞에 위치한 <'T'>는 T가 타입 매개변수임을 알리는 표시임을 알 수 있어야한다.
제네릭 메소드 호출
class BoxFactory{
public static <T> Box<T> makeBox(T o){
Box<T> box = new Box<T>();
box.set(o);
return box;
}
}
제네릭 클래스는 인스턴스 생성시 자료형이 결정된다. 반면 제네릭 메소드는 '메소드 호출시에 자료형이 결정'된다.
Box<String> sBox = BoxFactory.<String>makeBox("sweet");
Box<Double> dBox = BoxFactory.<Double>makeBox(7.59);
위의 두 문장을 다음 두 문장으로 대신 할 수 있다.
Box<String> sBox = BoxFactory.makeBox("Sweet");
Box<Double> dBOx = BoxFactory.makeBox(7.59);
class Box<T>{
private T ob;
public void set(T o){
ob = o;
}
public T get(){
return ob;
}
}
class Unboxer{
public static<T> T openBox(Box<T> box){
return box.get();
}
}
public class GenericMethodBoxMaker2 {
public static void main(String[] args) {
Box<String> box = new Box<>();
box.set("My Generic Method");
String str = Unboxer.openBox(box);
System.out.println(str);
}
}
class Unboxcer{
public static <T> openBox(Box<T> box){
return box.get();
}
}
반환형이 T이고 전달인자의 자료형이 Box<T>인 경우이다.
이 메소드의 호출방법은
public static void main(String[] args){
Box<String> box = new Box<>();
box.set("My Generic Method");
String str = Unboxcer.openBox(box);
}
위의 메소드 호출에서는 T가 String이어야 되니 타입 이자가 String으로 결정되었다.
제네릭 메소드의 제한된 타입 매개변수 선언
제네릭 클래스와 마찬가지로 제네릭 메소드도 호출시 전달되는 타입 인자를 제한할 수 있다. 그리고 제네릭 클래스의 타입 인자를 제한할 때 생기는 특성이 제네릭 메소드의 타입 인자를 제한할 때에도 생긴다.
class box<T extends Eatable>{...}
class Box<T>{
private T ob;
public void set(T o){
ob = o;
}
public T get(){
return ob;
}
}
class BoxFactory{
public static <T extends Number> Box<T> makeBox(T o){
Box<T> box = new Box<>();
box.set(o);
System.out.println("Boxed data : " + o.intValue());
return box;
}
}
class Unboxer{
public static <T extends Number> T openBox(Box<T> box){
System.out.println("Unboxced data : " + box.get().intValue());
return box.get();
}
}
public class BoundedGenericMethod {
public static void main(String[] args) {
Box<Integer> sBox = BoxFactory.makeBox(5959);
int n = Unboxer20.openBox(new Box20<>());
System.out.println("Returned data : "+ n);
}
}
public static <T extends Number> Box<T> makeBox(T o){
Box<T> box = new Box<>();
box.set(o);
System.out.println("Boxed data : " + o.intValue());
return box;
}
public static <T extends Number> T openBox(Box<T> box){
System.out.println("Unboxced data : " + box.get().intValue());
return box.get();
}