Study/Effective Java
-
아이템 33. 타입 안전 이종 컨테이너를 고려하라Study/Effective Java 2024. 12. 22. 19:17
제네릭은 하나의 컨테이너에서 매개변수화할 수 있는 타입의 수가 제한된다.하지만 더 유연한 수단이 필요하다고 해보자. 컨테이너 대신 키를 매개변수화한 다음, 컨테이너에 값을 넣거나 뺄 때 매개변수화한 키를 함께 제공하면 된다. 이러한 설계 방식을 타입 안전 이종 컨테이너 패턴(type safe heterogeneous container pattern)이라고 한다.타입 안전하지 않은 예제 먼저 보자.public class Favorites { private Map map = new HashMap(); public void put(Class clazz, Object value) { this.map.put(clazz, value); } public Object get(Class..
-
아이템 32. 제네릭과 가변인수를 함께 쓸 때는 신중하라Study/Effective Java 2023. 10. 12. 08:53
제네릭 varargs 배열 매개변수에 값을 저장하는 것은 안전하지 않다. 아이템 28의 @SafeVarags 내용과 연결 거의 모든 제네릭과 매개변수화 타입은 실체화되지 않는다. 제네릭은 배열로 사용할 수 없다. 하지만 가변인수 메서드를 호출하면 가변인수를 담기 위한 배열이 자동으로 하나 만들어진다. 우리가 직접 만들 수는 없지만 자바 내부적으로는 제네릭의 배열이 만들어지는 것이다. 그래서 메서드를 선언할 때 실체화 불가 타입으로 varargs 매개변수를 선언하면 컴파일러가 경고를 보낸다. warning : Possible heap pollution from parameterized vararg type 매개변수화 타입의 변수가 타입이 다른 객체를 참조하면 힙 오염이 발생하기 때문이다. ✔️ Heap p..
-
아이템 31. 한정적 와일드카드를 사용해 API 유연성을 높여라Study/Effective Java 2023. 9. 23. 09:37
매개변수화 타입은 불공변(invariant)이다. ▼ 와일드 카드 타입을 사용하지 않은 예제 public class Stack { private E[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; // 코드 29-3 배열을 사용한 코드를 제네릭으로 만드는 방법 1 (172쪽) // 배열 elements는 push(E)로 넘어온 E 인스턴스만 담는다. // 따라서 타입 안전성을 보장하지만, // 이 배열의 런타임 타입은 E[]가 아닌 Object[]다! @SuppressWarnings("unchecked") public Stack() { elements = (E[]) new Object[DEFA..
-
아이템 30. 이왕이면 제네릭 메서드로 만들라Study/Effective Java 2023. 9. 7. 07:15
제네릭 메서드 작성법은 제네릭 타입 작성법과 비슷하다. ▼ 문제가 있는 메서드 : Raw type 사용 public class Union { // 코드 30-1 로 타입 사용 - 수용 불가! (아이템 26) public static Set union(Set s1, Set s2) { Set result = new HashSet(s1); result.addAll(s2); return result; } } 클라이언트 사용시 런타임에 ClassCastException이 발생할 수 있는 코드다. 안전하게 만들기 위해 메서드 선언에서의 세 집합(입력 2개, 반환 1개)의 원소 타입을 타입 매개변수로 명시하고, 메서드 안에서도 이 타입 매개변수만 사용하게 수정하면 된다. 타입 매개변수 목록은 메서드의 접근 제한자와 ..
-
아이템 29. 이왕이면 제네릭 타입으로 만들라Study/Effective Java 2023. 9. 7. 06:40
제네릭 타입을 새로 만드는 일은 조금 어렵지만 배워두면 그만한 값어치는 충분히 한다. ▼ Generic이 절실한 강력 후보 // Object를 이용한 제네릭 스택 (170-174쪽) public class Stack { private Object[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public Stack() { elements = new Object[DEFAULT_INITIAL_CAPACITY]; } public void push(Object e) { ensureCapacity(); elements[size++] = e; } public Object pop() { if (size ..
-
아이템 28. 배열보다는 리스트를 사용하라Study/Effective Java 2023. 9. 1. 07:21
배열과 제네릭은 잘 어울리지 않는다. 배열은 공변(covariant), 제네릭은 불공변(invariant)이다. Sub가 Super의 하위 타입이라면 배열 Sub[]는 배열 Super[]의 하위타입이다. 공변, 즉 함께 변한다. 반면, 제네릭은 불공변이다. // 공변 Object[] anything = new String[10]; // String 타입을 Object 타입으로 담을 수 있다. 타입이 변한다. anything[0] = 1; // java.lang.ArrayStoreException! 컴파일러가 못잡는다. String이 Object의 하위 타입이므로 배열 String[]은 배열 Object[]의 하위 타입이 된다. 위 코드는 문법상 허용된다. 하지만 anything[0]에 int값을 넣을 수..
-
[JAVA] AnnotationStudy/Effective Java 2023. 8. 25. 07:22
@Documented : javadoc을 만들 때 annotation 정보가 포함된다. @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Documented { } Document Annotation 코드를 보면 런타임시 참조할 수 있고 Annotation Type에만 선언이 가능하다. ▼ 예제 @Documented public @interface MyAnnotation { } Annotation에 사용 가능하다. @Retention : annotation 정보를 언제까지 참조할 수 있는지 설정한다. @Documented @Retention(RetentionPolicy.R..
-
아이템 27. 비검사 경고를 제거하라Study/Effective Java 2023. 8. 25. 06:39
비검사 (unchecked) 경고란? 컴파일러가 타입 안정성을 확인하는데 필요한 정보가 충분치 않을 때 발생시키는 경고 checked/unchecked exception이랑은 관련 없다. 비검사 형변환 경고, 비검사 메서드 호출 경고, 비검사 매개변수화 가변인수 타입 경고, 비검사 변환 경고, … Set names = new HashSet(); Raw 타입을 사용하여 비검사 경고가 발생한다. 할 수 있는 한 모든 비검사 경고를 제거하라 모두 제거한다면 그 코드는 타입 안정성이 보장된다. 경고를 제거할 수 없지만 안전하다고 확신한다면 @SuppressWarnings(”unchecked”) 애노테이션을 달아 경고를 숨기자 안전하다고 검증된 비검사 경고를 숨기지 않고 그대로 두면, 진짜 문제를 알리는 새로운 ..