손영배 블로그 누구나 쉽게 이해하고 습득하기
제네릭이 무엇인가? 본문
왜 제네릭을 사용해야 하는가?
- 제네릭은 클래스, 인터페이스, 메소드를 정의할 때 타입(Type)을 파라미터(parameter)로 사용할 수 있도록 한다.
- 타입 파라미터는 코드 작성 시 구체적인 타입으로 대체되어 다양한 코드를 생성하도록 해준다.
장점
- 제네릭 타입을 이용함으로써 잘못된 타입이 사용될 수 있는 문제를 컴파일 과정에서 제거할 수 있다.
- 컴파일 시 강한 타입 체크를 할 수 있다.
- 타입 변환(casting)을 제거한다.
비제네릭 코드는 불필요한 타입 변환을 하기 때문에 프로그램 성능에 악영향을 미친다.
List list = new ArrayList();
list.add("hello");
String str = (String) list.get(0); //
List에 저장되는 요소를 String 타입으로 국한하기 때문에 요소를 찾아올 때 타입 변환을 할 필요가 없어 프로그램 성능이 향상된다.
List<String> list = new ArrayList<String>();
list.add("hello");
String str = list.get(0); //타입 변환을 하지 않는다.
제네릭 타입(class<T>, interface<T>)
- 제네릭 타입은 타입을 파라미터로 가지는 클래스와 인터페이스를 말한다.
public class 클래스명<T> {...}
public interface 인터페이스명<T> {...}
- 타입 변환이 빈번해지면 전체 프로그램 성능에 좋지 못한 결과를 가져올 수 있다. 성능저하
//문제점을 야기하는 코드
public class Box{
private Object object;
public void set(Object object) { this.object = object; }
public Object get() { return object; }
}
public class Apple { }
public class BoxExample {
public static void main(String[] args){
Box box = new Box();
box.set("홍길동"); // String -> Object (자동 타입 변환)
String name = (String) box.get(); // Object -> String (강제 타입 변환)
box.set(new Apple()); //Apple -> object(자동 타입 변환)
Apple apple = (Apple) box.get(); //Object -> Apple (강제 타입 변환)
}
}
//제네릭으로 해결
public class Box<T> {
private T t;
public T get() { return t };
public void set(T t) { this.t = t; }
}
public class BoxExample {
public static void main(String[] args) {
Box<String> box1 = new Box<String> ();
box1.set("hello");
String str = box1.get();
Box<Integer> box2 = new Box<Integer>();
box2.set(6);
int value = box2.get();
}
}
//제네릭은 클래스를 설계할 때 구체적인 타입을 명시하지 않고, 타입 파라미터로 대체했다가
//실제 클래스가 사용될 때 구체적인 타입을 지정함으로써 타입 변환을 최소화 시킨다.
멀티 타입 파라미터( class<K,V,.....>, interface<K, V, .......> )
public class Product <T, M>{
private T kind;
private M model;
public T getKind() { return this.kind; }
public M getModel() { return this.model; }
public void setKind(T kind) { this.kind = kind; }
public void setModel(M model) { this.model = model; }
public static void main(String[] args) {
Product<Tv, String> product1 = new Product<Tv, String>();
product1.set(new Tv());
product1.setModel("스마트Tv");
Tv tv = product1.getKind();
String tvModel = product1.getModel();
}
}
제네릭 메소드( <T, R> R method(T t) )
- 제네릭 메소드는 매개타입과 리턴 타입으로 타입 파라미터를 갖는 메소드를 말한다.
public <타입파라미터...> 리턴타입 메소드명(매개변수, , ,..) { ... }
public <T> Box<T> boxing(T t ) { ... }
public class Util {
public static <T> Box<T> boxing(T t) {
Box<T> box = new Box<T>();
box.set(t);
return box;
}
public static void main(String[] args) {
Box<Integer> box1 = Util.boxing(100);
int intValue = box1.get();
Box<String> box2 = Util.boxing("홍길동");
String strValue = box2.get();
}
}
'Interview' 카테고리의 다른 글
추상클래스(abstract) (0) | 2019.08.31 |
---|---|
인터페이스(interface)란? (0) | 2019.08.31 |
GET방식과 POST 방식의 차이에 대해서 (0) | 2019.06.19 |
프로그램(Program)과 프로세스(process)와 스레드(thread)의 차이 (0) | 2019.06.19 |
백 엔드 개발자가 알아야 할 것들 (0) | 2019.06.14 |