본문 바로가기

개발/이펙티브 자바

Effective Java ( 이펙티브 자바 ) - 아이템 59 라이브러리를 익히고 사용하라 무작위 정수 하나를 생성하고 싶다고 해보자. 값의 범위는 0부터 명시한 수 사이다. static Random rnd = new Random(); static int random(int n) { return Math.abs(rnd.nextInt()) % n; } 괜찮은 듯 보여도 문제를 세 가지나 내포하고 있다. n이 그리 크지 않는 2의 제곱수라면 얼마 지나지 않아 같은 수열이 반복된다. n이 2의 제곱수가 아니라면 몇몇 숫자가 평균적으로 더 자주 반환된다. n 값이 크면 이 현상은 더 두드러진다. 다음 코드는 예시를 위해 필자가 신중히 선택한 범위에서 무작위 수를 백만개를 생성한 다음, 그중 중간 값보다 작은게 몇 개인지를 출력한다. public static void mai.. 더보기
Effective Java ( 이펙티브 자바 ) - 아이템 58 전통적인 for문보다는 for-each 문을 사용하라 전통적인 for문으로 컬렉션과 배열을 순회하는 코드다. for (Iterator i = c.iterator(); i.hasNext(); ) { Element e = i.next(); } for (int i=0; i< a.length; i++) { ... } while문 보다는 낫지만 가장 좋은 방법은 아니다. 반복자와 인덱스 변수는 모두 코드를 지저분하게 할 뿐 진짜 필요한건 원소들뿐이다. 쓰이는 요소 종류가 늘어나면 오류가 생길 가능성이 높다. 컬렉션이냐 배열이냐에 따라 코드 형태가 상당히 달라지므로 주의해야 한다. 이상의 문제는 for-each 문을 사용하면 모두 해결된다. 정식 이름은 '향상된 for 문(enhanced for statement).. 더보기
Effective Java ( 이펙티브 자바 ) - 9장 - 아이템 57 일반적인 프로그래밍 원칙 - 9장 지역변수의 범위를 최소화하라 지역변수의 유효 범위를 최소로 줄이면 코드 가독성과 유지보수성이 높아지고 오류 가능성은 낮아진다. 지역변수의 범위를 줄이는 가장 강력한 기법은 역시 '가장 처음 쓰일 때 선언하기'다. 지역변수를 생각 없이 선언하다 보면 변수가 쓰이는 범위보다 너무 앞서 선언하거나, 다 쓴 뒤에도 여전히 살아 있게 되기 쉽다. 지역변수의 범위는 선언된 지점부터 그 지점을 포함한 블록이 끝날 때까지임을 명심하자. 거의 모든 지역변수는 선언과 동시에 초기화해야 한다. 초기화에 필요한 정보가 충분하지 않다면 충분해질 때까지 선언을 미뤄야 한다. try-catch문은 이 규칙에서 예외다. 변수 초기화 표현식에서 검사 예외를 던질 가능성이 있다면 try 블록 안에서 초.. 더보기
Effective Java ( 이펙티브 자바 ) - 아이템 51 메서드 시그니처를 신중히 설계하라 이번 아이템에는 개별 아이템으로 두기 애매한 API 설계 요령들을 모아 놓았다. 배우기 쉽고, 쓰기 쉽고, 오류 가능성이 적은 API를 만들 수 있을 것이다. 메서드 이름을 신충히 짓자 항상 표준 명명 규칙을 따라야 한다. 일관되고, 널리 받아들여지는 이름을 사용하는 것이다. 긴 이름은 피하자. 편의 메서드를 너무 많이 만들지 말자 메서드가 너무 많은 클래스는 익히고, 사용하고, 문서화하고, 테스트하고, 유지보수하기 어렵다. 인터페이스도 마찬가지다. 메서드가 너무 많으면 이를 구현하는 사람과 사용하는 사람 모두를 고통스럽게 한다. 확신이 서지 않으면 만들지 말자. 매개변수 목록은 짧게 유지하자 4개 이하가 좋다. 일단 4개가 넘어가면 기억하기가 쉽지 않다. IDE를 사용.. 더보기
Effective Java ( 이펙티브 자바 ) - 아이템 50 적시에 방어적 복사본을 만들라 자바는 안전한 언어다. 자바를 쓰는 즐거움 중 하나다. 하지만 아무리 자바라 해도 다른 클래스로부터의 침범을 아무런 노력 없이 다 막을 수 있는 건 아니다. 그러니 클라이언트가 여러분의 불변식을 깨뜨리려 혈안이 되어 있다고 가정하고 방어적으로 프로그래밍해야 한다. 충분한 시간을 투자하자. 어떤 객체든 그 객체의 허락 없이는 외부에서 내부를 수정하는 일은 불가능하다. 하지만 주의를 기울이지 않으면 자기도 모르게 내부를 수정하도록 허락하는 경우가 생긴다. 흔히 발생하는 문제다. 예컨대 기간을 표현하는 다음 클래스는 한번 값이 정해지면 변하지 않도록 할 생각이었다. public final class Period { private final Date start; private fi.. 더보기
Effective Java ( 이펙티브 자바 ) - 아이템 49 - 8장 - 메서드 이번 장에서는 메서드를 설계할 때 주의할 점들을 살펴본다. 구체적으로는 매개변수와 반환값을 어떻게 처리해야 하는지, 메서드 시그니처는 어떻게 설계해야 하는지, 문서화는 어떻게 해야 하는지를 다룬다. 생성자에도 적용된다. 주요 관점은 사용성, 견고성, 유연성에 집중한다 매개변수가 유효한지 검사하라 메서드와 생성자 대부분은 입력 매개변수의 값이 특정 조건을 만족하기를 바란다. 객체 참조는 null이 아니어야 하는 식이다. 이런 제약은 반드시 문서화해야 하며 메서드 몸체가 시작되기 전에 검사해야 한다. "오류는 가능한 한 빨리 (발생한 곳에서) 잡아야 한다"는 일반 원칙의 한 사례이기도 하다. 메서드 몸체가 실행되기 전에 매개변수를 확인한다면 즉각적이고 깔끔한 방식으로 예외를 던질 수 있다. 그렇지 못하면, .. 더보기
Effective Java ( 이펙티브 자바 ) - 아이템 48 스트림 병렬화는 주의해서 적용하라 주류 언어중, 동시성 프로그래밍 측면에서 자바는 항상 앞서갔다. wait/notify -> Executor -> fork-join -> parallel 스트림의 순서로 자바로 동시성 프로그램을 작성하기가 점점 쉬워지고는 있으나, 이를 올바르고 빠르게 작성하는 일은 여전히 어려운 작업이다. 동시성 프로그래밍을 할 때는 안전성(safety)과 응답 가능(liveness) 상태를 유지하기 위해 애써야 하는데, 병렬 스트림 파이프라인 프로그래밍에서도 다를 바 없다. 아이템 45에서 다루었던 메르센 소수를 생성하는 프로그램을 다시 살펴보자. public static void main(String[] args) { primes().map(p -> TWO.pos(p.intValueE.. 더보기
Effective Java ( 이펙티브 자바 ) - 아이템 47 반환 타입으로는 스트림보다 컬렉션이 낫다 원소 시퀸스를 반환하는 메서드는 수없이 많다. 자바 7까지는 Collections, Set, List 같은 컬렉션 인터페이스, 혹은 Iterable이나 배열을 썼다. for-each 문에서만 쓰이거나 반환된 원소 시퀸스가 일부 Collection 메서드를 구현할 수 없을 때는 Iterable 인터페이스를 썼다. 반환 원소들이 기본타입이거나 성능에 민감한 상황이라면 배열을 썼다. 그런데 자바 8이 스트림이라는 개념을 들고 오면서 이 선택이 아주 복잡한 일이 되어버렸다. 아이템 45에서 이야기했듯이 스트림은 반복을 지원하지 않는다. 따라서 스트림과 반복을 알맞게 조합해야 좋은 코드가 나온다. 여기서 재미난 사실 하나! 사실 Stream 인터페이스는 Iterable 인.. 더보기