반응형

스터디/이펙티브 자바 50

[Effective Java] Item40. @Override 애너테이션을 일관되게 사용하라

@Override @Override 애너테이션은 메서드 선언에만 달 수 있으며, 해당 메서드가 상위 타입의 메서드를 재정의했다는 것을 알려줍니다. 붙이지 않아도 컴파일 오류가 나지 않지만 버그를 예방할 수 있기 때문에 사용하는 것이 좋습니다. @Override를 사용하지 않으면? public class MyClass { private final int a; public MyClass(int a) { this.a = a; } public boolean equals(MyClass m) { return m.a == a; } public int hashCode() { return a; } public static void main(String[] args) { Set set = new HashSet(); for..

[Effective Java] Item39. 명명 패턴보단 어노테이션

명명 패턴 Junit 3까지 테스트 메서드의 이름이 test로 시작해야만 했던 것과 같이 이름을 짓는 규칙 명명 패턴의 문제 오타 올바른 프로그램 요소만 사용되리란 보증이 없음 프로그램 요소를 매개변수로 전달할 마땅한 방법이 없음 어노테이션 jdk 5부터 추가된 기능, 추가적인 정보를 제공하는 메타 데이터 메타 데이터이기 때문에 비즈니스 로직에 직접적인 영향을 주진 않지만, 이 정보에 따라서 실행 흐름을 변경할수 있는 코딩이 가능하여 더 깔끔한 코딩이 가능해 질 수 있음 마커 어노테이션 (Marker annotation) @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Test {} 메타 어노테이션: 어노테..

[Effective Java] Item38. 확장가능한 열거 타입이 필요하면 인터페이스

열거 타입과 확장 열거 타입은 거의 모든 상황에서 타입 안전 열거 패턴보다 우수하지만 확장하는 것은 좋지 않음 확장 타입의 원소는 기반 타입의 원소로 취급하지만 그 반대는 성립하지 않음 기반 타입과 확장 타입의 원소 모두 순회할 방법도 마땅치 않음 확장성을 높이려면 고려할 요소가 늘어남 확장 가능한 열거 타입 public interface Operation { double apply(double x, double y); } public enum BasicOperation implements Operation { PLUS("+") { public double apply(double x, double y) { return x + y; } }, MINUS("-") { public double apply(dou..

[Effective Java] Item 37. ordinal 인덱싱 대신 EnumMap

예제코드 public class Plant { enum LifeCycle { ANNUAL, PERNNIAL, BIENNIAL} final String name; final LifeCycle lifeCycle; public Plant(String name, LifeCycle lifeCycle) { this.name = name; this.lifeCycle = lifeCycle; } @Override public String toString() { return name; } } ordianl 인덱싱 Set[] plantsByLifeCycle = (Set[]) new Set[LifeCycle.values().length]; for (int i = 0 ; i < plantsByLifeCycle.length ; ..

[Effective Java] Item35. ordinal 대신 인스턴스 필드

public enum Role { CUSTOMER, SHOP_MANAGER; public int getAuth() { return ordinal(); } } 알바(PART_TIMER)를 추가 public enum Role { CUSTOMER, PART_TIMER, SHOP_MANAGER; public int getAuth() { return ordinal(); } } 문맥상 손님과 가게 사장 중간에 와야하므로 중간에 알바를 추가하면 순서가 달라지기 때문에 ordinal()메서드의 값이 달라짐 이 경우 ordinal()대신 인스턴스 필드에 값을 저장 public enum Role { CUSTOMER(0), SHOP_MANAGER(1); private final int auth; Role(int auth) ..

[Effective Java] Item34. int 대신 Enum

정수 열거 패턴(int enum pattern) - 사용 X 열거 타입이 생기기 전 공통적으로 사용되는 상수를 한데 묶어서 사용했었습니다. public static final int APPLE_FUJI = 0; public static final int APPLE_PIPPIN = 1; public static final int APPLE_GRANNY_SMITH = 2; public static final int ORANGE_NAVLE = 0; public static final int ORANGE_TEMPLE = 1; public static final int ORANGE_BLOOD = 2; 이런 식으로 사용한 것을 정수 열거 패턴(int enum pattern)이라고 합니다. 정수 열거 패턴의 단점 타..

[Effective Java] Item33. 타입 안전 이종 컨테이너를 고려

제네릭은 Set, Map 등의 컬렉션과 TreadLocal 등의 단일원소 컨테이너에도 흔히 사용됩니다. 이런 모든 쓰임에서 매개변수화 되는 대상은 원소가 아닌 컨테이너 자신입니다. 따라서 하나의 컨테이너에서 매개변수화 할 수 있는 타입의 수가 제한됩니다. Set에는 단 하나의 타입 매개변수만 허용되며, Map에는 key와 value에 해당하는 두 개의 타입 매개변수만 허용됩니다. 이런 타입 매개변수의 갯수를 유연하게 하는 방법이 있습니다. 컨테이너 대신 키를 매개변수화한 다음 컨테이너에 값을 넣거나 뺄 때 매개변수화한 키를 함께 제공하는 것입니다. 이러한 설계 방식을 타입 안전 이종 컨테이너 패턴이라고 합니다. public class Favorites { private Map, Object>입니다. 이때..

[Effective Java] Item32. 제네릭과 가변인수를 함께 쓸 때는 신중하게

가변인수(varargs) 메서드에 넘기는 인수의 개수를 클라이언트가 조절할 수 있게 해주는데, 컴파일시 배열로 처리 됩니다. 따라서 가변인수 매개변수에 제네릭이나 매개변수화 타입이 포함되면 아래와 같은 컴파일 경고가 발생합니다. public static void test(List... stringLists) { List intList = List.of(1); Object[] objects = stringLists; objects[0] = intList; // 힙 오염 String s = stringLists[0].get(0); // ClassCastException } 위 코드를 컴파일하면 아래와 같은 경고 메시지가 발생합니다. java: Test.java uses unchecked or unsafe o..

[Effective Java] Item31. 한정적 와일드카드를 사용해 API 유연성을 높여라

Item28에서 정리했던 것 처럼 매개변수화 타입은 불공변(invariant)입니다. 즉, List은 List의 하위타입이 아닙니다. 일반적으로는 이렇게 되는 것이 맞는 것 같습니다. 하지만 List에 Integer 타입을 추가하고 싶을 때가 있습니다. 매개변수화 타입은 불공변이기 때문에 불가능하지만 해결책은 있습니다. 한정적 와일드카드를 이용하는 것 입니다. 한정적 와일드 카드(Bounded Wildcards) Upper Bounded Wildcards: 타입제한을 풀어줄 때 사용, 제네릭 타입을 상위 제네릭 타입으로 묶을 때 사용 (List