제네릭 = 데이터 타입을 일반화한다, 클래스나 메소드에서 사용하는 내부의 타입을 외부에서 지정해주는 기법
제네릭 클래스
클래스 선언에 타입 매개변수가 쓰이면 이를 제네릭 클래스라 한다.
기본형태
class useBook<T> {}
예제)
class useBook<T> {
List<T> users = new ArrayList<>();
public void add(T user) {
users.add(user);
}
}
선언)
UserBook<Magician> magicianBook = new UserBook<>();
사용하는 이유:
1. 런타임에서 잡히는 에러(자료형에 대한 검증)가 컴파일에서 잡히기 때문에 시간을 절약할 수 있다.
2. 컴파일 타임에 자료형의 오류에 대한 검증을 수행하여 런타임에 자료형에 안전한 코드를 실행한다.
3. 반환값에 대한 타입 변환 및 타입 검사에 들어가는 노력을 줄일 수 있고, 형변환이 없어지므로 가독성이 좋아진다. (캐스팅 삭제 등)
제네릭 메소드
public <T> void add (T t) {}
<> 안의 타입으로 매개변수의 데이터 타입을 지정하고, 타입 파라미터의 범위는 메소드 블록 이내로 한정한다.
* 제네릭 메소드는 제네릭 클래스가 아니더라도 정의할 수 있다.
제네릭 클래스가 아닌 예)
class Name {
public <T> void printClassName(T t){
System.out.println(t.getClass().getName());
}
}
제네릭 클래스 인 예)
class Name <T> {
public <T> void printClassName(T t){
System.out.println(t.getClass().getName());
}
}
다음과 같이 제네릭 메소드를 호출해줬을 때이다.
public static void main(String[] args) {
Name name = new Name();
name.printClassName(1);
name.printClassName(1.11);
}
두 예제 모두 동일한 출력값을 가진다.
java.lang.Integer
java.lang.Double
상한 경계
T extends User
- 타입 매개변수의 클래스는 User 클래스이거나 User의 하위 클래스이어야 한다.
- User를 포함한 User 직계 자손 클래스들이 가능한 범위이다.
- 상위 클래스들은 불가능하므로 상한 경계이다.
하한 경계
T super User
- 타입 매개변수의 클래스는 User 클래스이거나 User의 상위 클래스이어야 한다.
- User를 포함한 User 직계 부모 클래스들이 가능한 범위이다.
- 하위 클래스들은 불가능하므로 하한 경계이다.
아래 코드는 List에 다른 타입 원소가 추가될 수 있으므로 user.add(user)에서 컴파일 에러가 발생한다.
class useBook<T> {
List<Users> users = new ArrayList<>();
public void add(T user) {
users.add(user);
}
}
<T>가 User의 하위클래스가 아닐 수 도 있기때문이다.
해결 코드
class useBook<T extends Users> {
List<Users> users = new ArrayList<>();
public void add(T user) {
users.add(user);
}
}
'언어 > JAVA' 카테고리의 다른 글
[Java] PECS(Producer-Extends, Consumer-Super) 공식 (0) | 2023.02.14 |
---|---|
[Java] 와일드카드 <?> (0) | 2023.02.13 |
[Java] 출력 3가지 방법 (0) | 2023.02.01 |
[Java] 입력 3가지 방법 (0) | 2023.02.01 |
댓글