지역변수의 범위를 최소화하라
- 가장 처음 쓰일 때 선언하자.
- 선언과 동시에 초기화해야 한다.
- 컬렉션이나 배열 순회
for (Element e : c) {
...
}
- 반복자가 필요할 때
for (Iterator<Element> i = c.iterator(); i.hasNext(); ) {
...
}
- 메서드를 작게 유지하고 한 가지 기능에 집중해라.
전통적인 for문 보다는 for-each문을 사용하라
- for-each문을 사용할 수 없는 상황
- 파괴적인 필터링 : 컬렉션을 순회하면서 선택된 원소를 제거해야 하는 경우 (자바 8에서는 Collection의 removeIf 메서드를 사용한다.)
- 변형 : 리스트나 배열을 순회하면서 그 원소의 값 일부 혹은 전체를 교체해야 하는 경우
- 병렬 반복 : 여러 컬렉션을 병렬로 순회해야 하는 경우
라이브러리를 익히고 사용하라
- 표준 라이브러리를 사용하면 그 코드를 작성한 전문가의 지식과 다른 프로그래머들의 경험을 활용할 수 있다.
- 메이저 릴리즈마다 주목할 만한 수많은 기능이 라이브러리에 추가된다. (릴리즈 노트를 한번쯤은 읽어보자.)
- 자바 프로그래머라면 적어도 java.lang, java.util, java.io와 그 하위 패키지들에는 익숙해져야 한다.
- 일반적으로 라이브러리의 코드는 직접 작성한 것 보다 품질이 좋고, 점차 개선될 가능성이 크다.
정확한 답이 필요하다면 float와 double은 피하라
- float, double 타입은 넓은 범위의 수를 빠르게 정밀한 '근사치'로 계산하도록 설계되었다.
- 금융 계산에는 BigDecimal, int, long을 사용해야 한다.
- 소수점 추적을 시스템에 맡기고, 코딩 시의 불편함이나 성능 저하를 신경 쓰지 않겠다면 BigDecimal을 써라.
- 성능이 중요하고, 소수점을 직접 추적할 수 있고, 숫자가 너무 크지 않으면 int나 long을 사용하라.
박싱된 기본 타입보다는 기본 타입을 사용하라
- 기본 타입은 간단하고 빠르다.
- 박싱된 기본 타입에 == 연산자를 사용하면 오류가 일어난다. (객체 참조의 식별성 비교가 일어난다.)
- 기본 타입과 박싱된 기본 타입을 혼용한 연산에서는 박싱된 기본 타입의 박싱이 자동으로 풀린다. (언박싱 과정에서 NullPointerException을 던질 수 있다.)
- 기본 타입을 박싱하는 작업은 필요 없는 객체를 생성하는 부작용을 발생시킨다.
다른 타입이 적절하다면 문자열 사용을 피하라
- 문자열은 다른 값 타입을 대신하기에 적합하지 않다.
- 문자열은 잘 못 사용하면 번거롭고, 덜 유연하고, 느리고, 오류 가능성도 크다.
- 문자열을 잘 못 사용하는 흔한 예로는 기본 타입, 열거 타입, 혼합 타입이 있다.
문자열 연결은 느리니 주의하라
- 문자열 연결 연산자로 문자열 n개를 잇는 시간은 n^2에 비례한다.
- 성능을 포기하고 싶지 않다면 String 대신 StringBuilder를 사용하자.
객체는 인터페이스를 사용해 참조하라
- 적합한 인터페이스만 있다면 매개변수뿐 아니라 반환값, 변수, 필드를 전부 인터페이스 타입으로 선언하라.
- 인터페이스를 타입으로 사용하는 습관을 길러두면 프로그램이 훨씬 유연해질 것이다.
- 적합한 인터페이스가 없다면 클래스의 계층구조 중 피요한 기능을 만족하는 가장 덜 구체적인(상위의) 클래스를 타입으로 사용하자.
리플렉션보다는 인터페이스를 사용하라
- 리플렉션을 이용하면 발생하는 문제점
- 컴파일타임 타입 검사가 주는 이점을 하나도 누릴 수 없다.
- 리플렉션을 이용하면 코드가 지저분하고 장황해진다.
- 성능이 떨어진다.
- 리플렉션은 제한된 형태로만 사용해야 그 단점을 피하고 이점만 취할 수 있다.
- 리플렉션은 인스턴스 생성에만 쓰고, 이렇게 만든 인스턴스는 인터페이스나 상위 클래스로 참조해 사용하자.
네이티브 메서드는 신중히 사용하라
- 성능을 개선할 목적으로 네이티브 메서드를 사용하는 것은 거의 권장하지 않는다.
최적화는 신중히 하라
- 빠른 프로그램보다는 좋은 프로그램을 작성하라.
- 성능을 제한하는 설계를 피하라
- API를 설계할 때 성능에 주는 영향을 고려하라.
- 성능을 위해 API를 왜곡하는건 매우 안 좋은 생각이다.
- 각각의 최적화 시도 전후로 성능을 측정하라.
일반적으로 통용되는 명명 규칙을 따르라
식별자 타입 |
예 |
패키지와 모듈 |
org.junit.jupiter.api, com.google.common.collect |
클래스와 인터페이스 |
Stream, FutureTask, LinkedHashMap, HttpClient |
메서드와 필드 |
remove, groupingBy, getCrc |
상수 필드 |
MIN_VALUE, NEGATIVE_INFINITY |
지역 변수 |
i, denom, houseNum |
타입 매개변수 |
T, E, K, V, X, R, U, V, T1, T2 |
'책 > Effective Java' 카테고리의 다른 글
동시성 (0) | 2020.03.28 |
---|---|
예외 (0) | 2020.03.27 |
메서드 (0) | 2020.03.24 |
람다와 스트림 (0) | 2020.03.20 |
열거 타입과 애너테이션 (0) | 2020.03.18 |