조슈아 블로크 님의 "Effective Java" 책을 정리한 포스팅 입니다.
1. 제네릭과 가변인수를 함께 쓸 때는 신중하라
제네릭 varargs 배열 매개변수에 값을 저장하는 것은 안전하지 않음
- 가변인수는 내부적으로 타입의 배열을 생성함
- 제네릭 타입의 배열은 생성 불가
- 생성 시, 힙 오염 발생
힙 오염
public class Example {
public static <T> void unsafeMethod(T... args) {
Object[] array = args; // args는 T[] 타입 배열로 생성됨
array[0] = "String"; // 런타임에는 Object로 처리되어 컴파일 가능
T t = args[0]; // ClassCastException 발생 가능
}
public static void main(String[] args) {
unsafeMethod(1, 2, 3); // <T>는 Integer로 추정되지만 String 삽입 가능
}
}
- 제네릭 타입의 배열 생성이나 사용에서 발생하는 문제
- 배열이 타입 안정성을 맇고 잘못된 타입의 객체를 저장하거나 반환하게 되는 현상
@SafeVarargs
- 컴파일러에 이 메서드는 가변인수 배열을 안전하게 처리한다는 것을 알림
사용 조건
- 인자는 모두 같은 타입이여야 함
- private 메서드 or, static 메서드 or final 메서드여야 함
2. 타입 안전 이종 컨테이너를 고려하라
- 다양한 타입의 값을 안전하게 저장하고 조회할 수 있도록 설계된 컨테이너
- 제네릭 타입 시스템이 값의 타입이 키과 같음을 보장
타입 토큰
Class<String> stringClass = String.class;
Class<Integer> integerClass = Integer.class;
- 컴파일 타임에 제공되는 타입 정보를 런타임까지 보존하는 방법
- 클래스 리터럴을 통해 타입 토큰을 표현
Favorites
public class Favorite {
private Map<Class<?>, Object> favorites = new HashMap<>();
public <T> void putFavorite(Class<T> type, T instance) {
favorites.put(Objects.requireNoneNull(type), instance);
}
public <T> T getFavorite(Class<T> type) {
return type.cast(favorites.get(type));
}
}
Favorites favorites = new Favorites();
// 다양한 타입의 값 저장
favorites.putFavorite(String.class, "Hello, World!");
favorites.putFavorite(Integer.class, 42);
favorites.putFavorite(Class.class, Favorites.class);
// 저장된 값 조회
String favoriteString = favorites.getFavorite(String.class);
Integer favoriteInteger = favorites.getFavorite(Integer.class);
Class<?> favoriteClass = favorites.getFavorite(Class.class);
System.out.println(favoriteString); // 출력: Hello, World!
System.out.println(favoriteInteger); // 출력: 42
System.out.println(favoriteClass); // 출력: class Favorites
'Java' 카테고리의 다른 글
[Effective Java] 6-2. 열거 타입과 애노테이션 (0) | 2024.12.31 |
---|---|
[Effective Java] 6-1. 열거 타입과 애노테이션 (0) | 2024.12.30 |
[Effective Java] 5-2. 제네릭: 권고 사항 (3) | 2024.12.28 |
[Effective Java] 5-1. 제네릭: 제한 사항 (0) | 2024.12.27 |
[Effective Java] 4-4. 클래스와 인터페이스: 클래스 (0) | 2024.12.27 |