[자바 라이브 스터디] 12주차 - 제네릭
- 목표) 자바의 제네릭에 대해 학습하세요.
1. 제네릭 사용법
- 정의) 컴파일 시의 타입 체크를 해줘서 메서드나 클래스가 다양한 타입의 객체 다룰 수 있게 해주는 기능
- 특징)
- 타입 안정성을 제공함
- 타입체크와 형변환 생략 가능해져 코드 간결해짐
- static 멤버에 T 사용 불가(T가 인스턴스 변수로 간주되기 때문)
- instanceof 연산자와 new 연산자의 피연산자로 T 사용 불가(컴파일 시점에 T가 뭔지 정확히 알아야 하기 때문)
- 사용)
UserUtils<T>와 같이 선언해 제네릭 클래스를 만들어두고,UserUtils<User>와 같이 제네릭 타입을 호출해 사용함
- 예시)
- 제네릭 타입을 클래스에 선언
- 클래스 옆에 <T>를 붙이고 Object 타입들을 T 타입으로 변경
- 적용 전
- 적용 후 → 제네릭 클래스 UserUtils<T>
- 제네릭 클래스의 객체 생성
- 참조변수와 생성자에 T 타입 대신에 사용할 실제 타입을 지정
- JDK 1.7부터
UserUtils<Teacher> userUtils= new UserUtils<>();도 가능 - 제네릭 도입 전 코드와의 호환 위해 아래도 허용은 하지만 경고 발생함 (지양하자)
- 만일 경고 안 뜨게 하고 싶다면, Object 타입으로라도 지정해주면 됨
2. 제네릭 주요 개념 (바운디드 타입, 와일드 카드)
- 바운디드 타입
- 정의) 제네릭 타입에서 타입 인자로 사용할 수 있는 타입을 제한하려는 경우 바운디드 타입 매개변수를 선언해 사용
- 사용) 타입 매개변수 이름(T), extends 키워드, 상위 바운드를 나열
UserUtils<T extends User>와 같이 사용하면User의 자손들만 담을 수 있게 제한 가능UserUtils<T extends Speakable>의Speakable가 인터페이스여도 마찬가지로 extends를 사용함UserUtils<T extends User & Speakable>과 같이 사용하면User의 자손이면서Speakable을 구현한 클래스만 타입 매개변수 T에 대입할 수 있음 (순서는 인터페이스보다 클래스가 먼저 와야 함)
- 와일드 카드
- 정의) 제네릭 타입이 달라도 오버로딩 성립하게 하려는 경우, 모든 타입을 대신할 수 있는 와일드카드 타입 사용
- 사용)
UserUtils<? extends User>와 같이 사용하면User의 자손들만 담을 수 있게 제한 가능UserUtils<? super User>와 같이 사용하면User의 조상들만 담을 수 있게 제한 가능UserUtils<?>와 같이 사용하면 모든 타입이 가능.UserUtils<? extends Object>와 동일
3. 제네릭 메소드 만들기
- 정의) 메서드 선언부에 제네릭 타입이 선언된 메서드
- 특징)
- 제네릭 타입의 선언 위치는 반환 타입 바로 앞임
- 제네릭 메서드는 제네릭 클래스가 아닌 클래스에도 정의 가능
- 사용)
- 적용 전)
- 적용 후)
4. Erasure
- 정의) 컴파일러가 제네릭 타입 이용해서 소스파일 체크하고 필요한 곳에 형변환 넣어주어 결국 컴파일 후 원시 타입으로 바뀜
- 과정)
- 제네릭 타입의 경계 제거
- 적용 전)
- 적용 후)
- 제네릭 타입 제거한 후 타입 일치하지 않으면 형변환 추가
- 적용 전)
- 적용 후)
- 추후 학습할 내용

![[백기선 자바] 제네릭](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F301eb74c-edaf-492f-9dca-9be8a3bbf75e%2F%25EC%25BA%25A1%25EC%25B2%2598.jpg?table=block&id=929b9d0e-770b-4d8d-8b1d-daa234b3a5d2&cache=v2)

