///////
Search

제네릭_이도현

개요

자바 1.5 버전부터 도입됨 (@ 애노테이션, enum 등과 같이)
소프트웨어적 해결이 아닌, 문법을 도입한 것
컴파일 시 타입 체크를 해주는 기능을 제공 > 즉, 타입이 이미 결정되어짐
예시
// 지네릭 사용 전 class Apple{ @Override public String toString() { return "나는 사과입니다."; } } class Orange{ @Override public String toString() { return "나는 오렌지 입니다."; } } class Box{ private Object obj; public void set(Object obj) { this.obj = obj; } public Object get() { return obj; } } //////////////// Box aBox = new Box(); Box oBox = new Box(); aBox.set(new Apple()); oBox.set(new Orange()); // 문제점 1. // 형변환 과정이 반복되면 프로그래머의 실수가 컴파일 과정에서 발견되지 않을 가능성이 높아진다. Apple ap = (Apple) aBox.get(); //형변환 과정이 반드시 필요함 Orange og = (Orange) oBox.get();////형변환 과정이 반드시 필요함 System.out.println(ap); System.out.println(og); } }
Java
복사
// 지네릭 사용 전 문제점 2. // 실수가 프로그램 실행 과정에서도 발견되지 않을 수 있다. public static void main(String[] args) { Box aBox = new Box(); Box oBox = new Box(); // 다음 두 문장은 프로그래머의 실수이다! aBox.set("Apple"); oBox.set("Orange"); System.out.println(aBox.get()); System.out.println(oBox.get()); }
Java
복사

제네릭 기반의 클래스 정의 > 인스턴스 생성

1.
인스턴스 생성 시 결정되는 자료형의 정보를 T로 대체
2.
T를 Apple, Orange로 결정하여 인스턴스 생성
// 제네릭 이후의 코드 public static void main(String[] args) { Box<Apple> aBox = new Box<Apple>(); // T를 Apple로 결정 Box<Orange> oBox = new Box<Orange>(); // T를 Orange로 결정 aBox.set(new Apple()); // 사과를 상자에 담는다. oBox.set(new Orange()); // 오렌지를 상자에 담는다. Apple ap = aBox.get(); // 사과를 꺼내는데 형 변환 하지 않는다. Orange og = oBox.get(); // 오렌지를 꺼내는데 형 변환 하지 않는다. System.out.println(ap); System.out.println(og); }
Java
복사

제네릭스의 용어

Box<T> : 제네릭 클래스. ‘T의 Box’ 또는 ‘T Box’라고 읽음
T : 타입 변수 또는 타입 매개변수 (T는 타입 문자)
Box : 원시 타입(raw type), 일반 클래스일 때 타입

제네릭 클래스의 제한

타입 인자 제한
class Box<T extends Number>{...}
Java
복사
인스턴스 생성 시 타입 인자로 Number or 이를 상속한 클래스만 올 수 있음
타입 인자 제한의 효과
number 안에 intValue 함수를 기본적으로 내부에서 사용하기를 원함 > 타입 제한을 미리 걸어버리는 것

제네릭 메소드

클래스 전부가 아닌 메소드 하나에 대해 제네릭으로 정의
⇒ 메서드의 선언부에 제네릭 타입이 선언된 메소드
class BoxFactory { public static <T> Box<T> makeBox(T o) { Box<T> box = new Box<T>(); // 상자를 생성하고, box.set(o); // 전달된 인스턴스를 상자에 담아서, return box; // 상자를 반환한다. } } // 제네릭 메소드의 T는 메소드 호출시점에 결정됨 Box<String> sBox = BoxFactory.<String>makeBox("Sweet"); Box<Double> dBox = BoxFactory.<Double>makeBox(7.59); // 7.59에 대해 오토 박싱 진행됨 // 다음과 같이 타입 인자 생략 가능 Box<String> sBox = BoxFactory.makeBox("Sweet"); Box<Double> dBox = BoxFactory.makeBox(7.59); // 7.59에 대해 오토 박싱 진행됨
Java
복사

제네릭 메소드의 제한된 타입 매개변수 선언

// <T extends Number>는 타입 인자를 Number를 상속하는 클래스로 제한함을 의미 public static <T extends Number> Box<T> makeBox(T o) { .... // 타입 인자 제한으로 intValue 호출 가능 System.out.println("Boxed data: " + o.intValue()); return box; } // 타입 인자를 Number를 상속하는 클래스로 제한 public static <T extends Number> T openBox(Box<T> box) { // 타입 인자 제한으로 intValue 호출 가능 System.out.println("Unboxed data: " + box.get().intValue()); return box.get(); }
Java
복사