github.com/whiteship/live-study/issues/14
목표자바의 제네릭에 대해 학습하세요. 학습할 것 (필수)
|
0. 제네릭이란?
자바5에 추가된 기능.
잘못된 타입이 사용될 수 있는 문제를 컴파일 과정에서 제거할 수 있게 됨.
타입 변환(casting)을 제거함.
제네릭 타입도 상속이 가능. 상속받은 child는 추가적인 타입 파라미터를 가질 수 있음.
기본 타입 인수 사용 불가
List list = new ArrayList();
list.add("hello");
String str = (String) list.get(0); // 타입 변환 필요
List<String> list = new ArrayList<String>();
list.add("hello");
String str = list.get(0); // 타입 변환을 하지 않는다.
1. 제네릭 사용법
제네릭 타입 (class<T>, interface<T>)
- 타입을 파라미터로 가지는 클래스와 인터페이스
- 클래스 or 인터페이스 뒤에 "<>" 부호가 붙고, 사이에 타입 파라미터가 위치
- 일반적으로 타입 파라미터는 대문자 알파벳 한 글자로 표현
public class 클래스명<T> {
}
public interface 인터페이스명<T> {
}
모든 종류에 객체를 저장할 수 있지만, 타입 변환은 발생하지 않도록 도와줌.
실제 예제 코드는 다음과 같다.
public class Box<T> { // 타입 파라미터 T를 사용하여 Object 타입을 t로 변경
private T t;
public T get() { return T; }
public void set(T t) { this.t = t; }
}
// Box 클래스로 객체를 생성할 때 구체적인 타입으로 변경된다
Box<String> box = new Box<String>();
// 타입 파라미터 T는 String 타입으로 변경되어 Box 클래스 내부는 다음과 같이 자동으로 재구성된다.
public class Box<String> {
private String t;
public String get() { return T; }
public void set(String t) { this.t = t; }
}
// 필드 타입, set 파라미터 와 get 리턴타입 모두 String 타입으로 변경되었기에 저장, 읽을 때 타입 변환 일어나지 않는다.
Box<String> box = new Box<String>();
box.set("hello");
String str = box.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;}
}
2. 제네릭 주요 개념 (바운디드 타입, 와일드 카드)
제한된 타입 파라미터( <T extends 최상위타입> ) : 클래스 혹은 인터페이스 타입 파라미터의 상위 타입을 제한
- 메소드의 중괄호 {} 안에서 타입 파라미터 변수로 사용 가능한 것은 상위 타입의 멤버(필드, 메소드)로 제한. 하위 타입에만 있는 필드, 메소드 사용 불가
public <T extends 상위타입> 리턴타입 메소드/인터페이스(매개변수, ... ) { //interface도 extends
}
와일드카드 타입 (<?>, <? extends ...> , <? super ...> )
코드에서 ?를 일반적으로 와일드카드(wildcard)라고 부른다. 제네릭 타입을 매개값이나 리턴 타입으로 사용할 때 구체적인 타입 대신에 와일드카드를 다음과 같이 세 가지 형태로 사용할 수 있다.
- 제네릭타입<?> : Unbounded Wildcards(제한없음)
- 타입 파라미터를 대치하는 구체적인 타입으로 모든 클래스나 인터페이스 타입이 올 수 있다.
- 제네릭타입<? extends 상위타입> : Upper Bounded Wildcards(상위클래스 제한)
- 타입 파라미터를 대치하는 구체적인 타입으로 상위 타입이나 하위 타입만 올 수 있다.
- 제네릭타입 <? super 하위타입> : Lower Bounded Wildcards (하위클래스 제한)
- 타입 파라미터를 대치하는 구체적인 타입으로 하위 타입이나 상위 타입이 올 수 있다.
3. 제네릭 메소드 만들기
제네릭 메소드(<T,R> R method(T t)) : 매개 타입과 리턴 타입으로 타입 파라미터를 갖는 메소드
선언 방법 : 리턴 타입 앞에 <> 기호를 추가하고 타입 파라미터를 기술한 다음, 리턴 타입과 매개 타입으로 타입 파라미터를 사용하면 됨.
public <타입파라미터, ...> 리턴타입 메소드명(매개변수 ,... ) {
}
// boxing() 제네릭 메소드는 <> 기호 안에 타입 파라미터 T를 기술한 뒤, 매개 변수 타입으로 T를 사용하였고,
// 리턴 타입으로 제네릭 타입 Box<T>를 사용했다.
public <T> Box<T> boxing(T t) {
}
제네릭 메소드 호출 방법
리턴타입 변수 = <구체적타입> 메소드명(매개값) ; //명시적으로 구체적 타입을 지정
Box<Integer> box = <Integer>boxing(100);
리턴타입 변수 = 메소드명(매개값); // 매개값을 보고 구체적 타입 추정
Box<Integer> box = boxing(100);
4. Erasure : 타입 소거
실행 시간에 제네릭은 모두 raw 형태 (제네릭 타입에서 타입이 소거된 타입).
즉, 제네릭 타입을 정의하면 해당 타입은 로(raw) 타입으로 컴파일된다.
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 class Product<Object, Object> {
private Object kind;
private Object model;
public Object getKind() { return this.kind; }
public Object getModel() { return this.model; }
public void setKind(Object kind){ this.kind = kind; }
public void setModel(Object model){ this.model = model;}
}
※ 오토 박싱/언박싱 등장
기본 데이터 타입에 대한 오토 박싱 / 언박싱 기능은 제네릭에 기반을 두고 있음
자바5 제네릭 등장 이전에는 컴파일러와 가상 머신이 데이터 타입을 추론할 수 없었기 때문에 기본 타입 데이터를 자동으로 래핑 데이터 타입으로 변환할 수 없었음.
하지만 제네릭 등장으로 이를 추론할 수 있게 되었고, 따라서 데이터 자동 변환이 가능해짐.
List<Integer> list = new ArrayList<Integer>();
for(int number : list) {
...
}
위 list의 제네릭 타입은 <Integer>이다. 해당 리스트에 int 데이터를 추가할 때 오토 박싱이 되면서 Integer 객체로 치환되었고, 다시 for each문에서 데이터 추출할 때도 Integer를 int로 오토 언박싱 되어서 처리가 된다.
■ 라이브 스터디
under bounded : 객체 정의할 때 사용 불가. 메소드 파라미터에 사용 가능, 클래스 뿐 아니라 인터페이스도 지원.
Dao 객체에 generic 적용하기.
런타임 중에 제네릭 타입을 알아낼 수 있을까? yes. 리플렉션으로 가능
출처 : 이것이 자바다 (신용권 저), 가장 빨리 만나는 코어 자바9 (카이 호스트만 저), Practical 모던 자바 (장윤기 저)
'Programming > Java' 카테고리의 다른 글
[whiteship 온라인 스터디] 15주차 과제: 람다식 (0) | 2021.03.04 |
---|---|
[whiteship 온라인 스터디] 13주차 과제: I/O (0) | 2021.02.27 |
[whiteship 온라인 스터디] 12주차 과제: 애노테이션 (0) | 2021.02.25 |
[whiteship 온라인 스터디] 11주차 과제: Enum (0) | 2021.02.24 |
[whiteship 온라인 스터디] 10주차 과제 - 멀티쓰레드 프로그래밍 (0) | 2021.02.24 |