본문 바로가기

STUDY/이펙티브자바

(44)
8-2) 방어적 복사본을 만들라 자바는 안전한 언어다 int nums1[4] = {1,2,3,4}; int nums2[4] = {5,6,7,8}; // 5 출력 std::cout 0) throw new IllegalArgumentException( this.start + " after " + this.end); } public Date start() { return new Date(start.getTime()); } public Date end() { return new Date(end.getTime()); } } // 이제 Period에 사용된 Date 객체의 값이 바뀌어도 영향이 없다. Date start = new Date(); Date end = new Date(); Period p = new Period(start, end);..
8-1) 매개변수가 유효한지 검사하라 매개변수 유효성 검사 // NullPointerException 발생 List nums = Collections.synchronizedList(null); ... 메소드나 생성자의 내부 동작은 정상적인 파라미터가 전달될 것이라는 것을 전제로 한다. 예를 인덱스 값은 음수가 아니고 객체는 null이 아니라는 것이다. 하지만 개발중 실수로 잘못된 값이 전달되지 않을거라는 보장은 없기 때문에 매개변수의 유효성 검사는 필요하다. 그리고 오류를 가능한 빨리 (근본적인 오류가 발생한 곳에서) 잡는것에도 도움이 된다. 위의 코드를 보면 Collections.synchronizedList(null); 메소드를 호출한 시점부터 파라미터 유효성 검사에 걸려서 에러가 발생한다. 하지만 만약 저 에러가 발생하지 않았다면, 멀..
6-3) 비트 필드 대신 EnumSet을 사용하라 비트 필드 열거 상수 public class Text { public static final int STYLE_BOLD= 1
6-2) ordinal 메소드 대신 인스턴스 필드를 사용하라 ordinal 사용한 예 public enum Ensemble { SOLO, DUET, TRIO, QUARTET, QUINTET, SEXTET, SEPTET, OCTETE, NONET, DECTET; public int numberOfMusicians() { return this.ordinal() + 1; } } enum에는 해당 상수사 몇 번째 위치인지를 반환하는 ordinal이라는 메소드가 존재한다. 그리고 개발자는 해당 메소드를 사용하여 기능을 구현하고싶은 유혹에 빠질 수 있다. 위의 코드는 합주의 종류를 나타내는 Ensemble과 여러 상수들이 있다. 그리고 연주자의 수를 반환하는 numberOfMusicians라는 메소드가 있는데 이를 ordinal 메소드를 이용하여 구현하였다. 당장은 문제가 ..
6-1) int 상수 대신 enum을 사용하라 정수 열거 패턴 public static final int FULL_TIME_JOB= 0; public static final int PART_TIME_JOB= 1; public static final int STAFF_RANK= 0; public static final int MANGER_RANK= 1; public static final int SENIOR_RANK= 2; 개발을 하다보면 상수 값을 사용해야 할 때가 있고 int에 static final 키워드를 추가해서 표현할 수 있다. 그리고 정의된 이름이 상수의 의미를 나타낸다. 정규직, 비정규직 고용형태를 0, 1의 상수로 정의하였고 사원, 대리, 주임 직급을 0, 1, 2의 상수로 정의하였다. 그리고 상수의 이름을 보면 그 의미에 맞게 정의되..
5-7) 타입 안전 이종 컨테이너를 고려하라 타입 안전 이종 컨테이너 public class Favorites { public void putFavorite(Class type, T instance); public T getFavorite(Class type); } 제네릭은 Set, Map 등 단일원소 컨테이너에 흔히 쓰인다. 이러한 컨테이너는 원소로 넣을 수 있는 타입의 수가 제한되어 있기 때문에 매개변수 타입의 수가 제한되어 있다. 하지만 더욱 유연한 컨테이너가 필요할 때도 있다. 다양한 타입의 원소를 가지는 컨테이너가 필요하다면 어떨까? 다양한 타입을 가지면서도 값을 넣거나 뺄 때 안전하게 사용할 수 있어야 할 것이다. 그리고 이를 타입 안전 이종 컨테이너라고 부른다. 위의 Favorites 클래스는 각 타입마다 좋아하는 객체를 넣을수 있는 ..
5-6) 제네릭과 가변인수를 함께 쓸 때는 신중하라 제네릭과 가변인수 // 제네릭과 가변인수를 함께 사용하면 컴파일러가 경고를 보낸다 // Type safety: Potential heap pollution via varargs parameter stringList public static void myFunc(List... stringLists) List intList = List.of(1); Object[] objects = stringLists; objects[0] = intList; // 힙 오염 발생 String s = stringLists[0].get(0); // ClassCastException 런타임 에러 발생 } 가변인수와 제네릭은 자바5때 함께 추가되었으나 함께 사용하기에는 까다롭다. 제네릭과 가변인수를 함게 사용하면 컴파일러는 힙 오염..
5-5) 한정적 와일드카드를 사용해 유연성을 높혀라 매개변수화 타입의 불공변성 // Integer 타입은 Number 타입을 상속했기때문에, num = intNum가 가능하다. Number num = 1; Integer intNum = 1; num = intNum; // Integer 타입은 Number 타입을 상속했지만, 매개변수 타입으로 전달되었을때는 그 관계가 유지되지 않는다. // 따라서 numStack = intStack 코드는 컴파일 에러가 발생한다. Stack numStack = new Stack(); Stack intStack = new Stack(); numStack = intStack; 매개변수화 타입은 불공변이다. 불공변이라는 말은 타입의 관계가 같이 변하지 않는다는 것을 말한다. 위의 코드를 보면 Integer 타입은 Number 타..