이번 아이템의 핵심은 “제네릭 클래스 이외에도 제네릭 메소드 또한 만들 수 있다”이다.
책에서는 이에 대해 제네릭 메소드 작성법을 설명하는 것이다. 핵심을 놓치지 말자..
제네릭
public class Student<T> {
static T name;
}
static 변수는 제네릭을 사용할 수 없다. 왜냐하면 Student 클래스가 인스턴스 되기 전에 static은 메모리에 올라가는데, 이때 name의 타입인 T가 결정되지 않기 때문이다.
static 메소드에도 제네릭을 사용하면 에러가 발생하는데, static 변수와 마찬가지로 Student 클래스가 인스턴스화 되기 전에 메모리에 올라가는데 T의 타입이 정해지지 않기 때문이다.
그러나 제네릭 메소드는 static이 가능하다.
어떻게 가능하냐면, 제네릭 메소드는 호출 시에 매개 타입을 지정하기 때문에 static이 가능하다.
public class Student<T> {
static <T> T getOneStudent(T id) {
return id;
}
}
주의해야 할 점은 Student에 지정한 제네릭 타입 <T>와 제네릭 메소드에 붙은 <T>는 같은 T를 사용하더라도 전혀 별개이다.
public interface List<E> extends Collection<E> {
boolean add(E e);
}
위 코드에서 List<E>의 E와 add 메소드의 매개변수 타입 E는 다를까?
이들은 같다.
그 이유는 제네릭 메소드를 사용하면 T가 지역변수로 바뀌기 때문이다.
public static void printAll(ArrayList<? extends Test> list1, ArrayList<? extends Test> list2) {
// 로직
}
public static <T extends Test> void printAll(ArrayList<T> list1, ArrayList<T> list2) {
// 로직
}
제네릭 메소드를 사용하지 않는다면 첫 번째와 같이 매개변수의 타입에 타입 제한을 해야 한다. 반면, 제네릭 메소드를 사용한다면 두 번째 코드처럼 변경할 수 있다.
제네릭 싱글턴 팩터리
- 불변 객체를 여러 타입으로 활용할 수 있게 만들어주는 팩터리 메소드
- 제네릭이 런타임에 타입 정보를 소거하기 때문에 하나의 객체를 어떤 타입으로든 매개변수화할 수 있다는 특징을 이용
- ex : Collections.reverseOrder(아이템 42), Collections.emptySet, Function.identity(아이템 59)
책에서는 Function.identity를 직접 구현하는 예시를 들었다. 그닥 새로운 내용은 아니므로 넘어가자..
Function.identity
- 제네릭 타입을 받아들이고 받은 인자를 그대로 반환하는 함수
Function<String, String> identityFunc = Function.identity();
identityFunc.apply("hello") // "hello" 반환
재귀적 타입 한정(recursive type bound)
- 제네릭 타입 매개변수가 자기 자신을 참조하는 제약 조건을 가지는 것
- 제네릭 타입 매개변수가 자기 자신 또는 그 하위 타입으로 한정되어야 함을 나타낸다.
- 예를 들어, <T extends Comparable<T>>는 T가 Comparable 인터페이스를 구현한 타입 또는 그 하위 타입이어야 함을 의미한다. 여기서 T는 자기 자신을 참조하는데 T는 Comparable<T>의 구현체가 되어야 하므로 재귀적으로 타입 한정이 발생한다.
- 정렬이나 비교 기능을 가진 클래스나 메서드에서 사용된다. 타입 매개변수 T를 자기 자신과 비교할 수 있어야 정확한 정렬이나 비교를 수행할 수 있다.
고냥 간단하게 말하면, 자기 자신을 참조를 한 번 더 하는 것..
'Language > Java' 카테고리의 다른 글
[effective java] 아이템 32. 제네릭과 가변인수를 함께 쓸 때는 신중하라. (0) | 2023.05.14 |
---|---|
[effective java] 아이템 31. 한정적 와일드카드를 사용해 API 유연성을 높이라. (0) | 2023.05.14 |
[effective java] 아이템 29. 이왕이면 제네릭 타입으로 만들라. (0) | 2023.05.09 |
[effective java] 아이템 28. 배열보다는 리스트를 사용하라. (0) | 2023.05.09 |
[effective java] 아이템 27. Unchecked Warning을 제거하라. (0) | 2023.05.09 |