이펙티브 자바 9장: 일반적인 프로그래밍 원칙

Adam·2024년 8월 22일
0

이펙티브 자바

목록 보기
8/10
post-thumbnail

지역변수의 범위를 최소화하라

지역변수의 유효 범위를 최소로 줄이면 코드 가독성과 유지보수성이 높아지고 오류 가능성은 낮아진다

지역변수의 범위를 줄이는 가장 강력한 기법은 가장 처음 쓰일 때 선언하는 것

거의 모든 지역변수는 선언과 동시에 초기화해야 한다

반복문에서 변수를 사용하려면 for 메서드가 while 메서드보다 좋다

지역변수를 최소화하려면 메서드를 작게 유지하고 한 가지 기능에 집중해야 한다

전통적인 for 문보다는 for-each문을 사용하라

enhanced for 문

for(Element e : elements){}

위와 같은 for-each 문은 명료하고, 유연하고 버그를 예방해준다.

for-each문을 사용하지 못하는 케이스

  1. 파괴적인 필터링: 컬렉션을 순회하면서 선택된 원소를 제거해야 되는 경우
  2. 변형: 리스트나 배열을 순회하면서 그 원소의 값 일부 혹은 전체를 교체해야 되면 배열의 인덱스를 사용해야 한다
  3. 병렬 반복: 여러 컬랙션을 병렬로 순회해야 한다면 각각의 반복자와 인덱스 변수를 사용해 엄격하게 제어해야 한다

라이브러리를 익히고 사용하라

표준 라이브러리 쓰는 장점

  1. 그 코드를 작성한 전문가의 지식과 경험을 활용할 수 있다
  2. 일과 크게 관련 없는 문제를 해결하느라 시간을 허비하지 않아도 된다
  3. 노력하지 않아도 성능이 지속해서 개선된다
  4. 기능이 점점 많아진다
  5. 다른 사람에게 낯익은 코드가 된다

정확한 답이 필요하다면 float와 double은 피하라

float과 double은 근사치로 계산하도록 설계되어서 정확한 계산에 쓰기에는 무리가 있다

정확한 계산을 위해선 BigDecimal, int 혹은 long을 사용해야 한다

박싱된 기본 타입보다는 기본 타입을 사용하라

기본 타입: int, double, boolean

참조 타입: String, List

박싱된 기본 타입: Integer, Double, Boolean

기본 타입과 박싱된 기본 타입의 차이점

  1. 기본 타입은 값만 가지고 있으나, 박싱된 기본 타입은 값에 더해 식별성이란 속성을 갖는다
  2. 기본 타입은 언제나 유효하나, 박싱된 기본 타입은 유효하지 않다(null을 가질 수 있다)
  3. 기본 타입이 시간과 메모리 사용면에서 더 효율적

박싱된 기본 타입에 == 연산자를 사용하면 오류가 일어난다

기본 타입과 박싱된 기본 타입을 혼용한 연산에서는 박싱된 기본 타입의 박싱이 자동으로 풀린다

컬랙션의 원소, 키 값으로 사용할 때는 박싱된 기본 타입을 사용해야 한다

다른 타입이 적절하다면 문자열 사용을 피하라

문자열은 다른 값 타입을 대신하기 적합하지 않다.

문자열은 열거 타입을 대신하기에 적합하지 않다

문자열은 혼합 타입을 대신하기에 적합하지 않다

문자열은 권한을 표현하기에 적합하지 않다

문자열 연결은 느리지 주의하라

문자열 연결 연산자로 문자열 n개를 잇는 시간은 n제곱에 비래한다

성능을 위해선 String 대신 StringBuilder을 사용하자

객체는 인터페이스를 사용해 참조하라

적합한 인터페이스만 있다면 매개변수뿐 아니라 반환값, 변수, 필드를 전부 인터페이스 타입으로 선언하는 것이 좋다

// 인터페이스 타입으로 사용해 좋은 예
Set<Son> sonSet = new LinkedHashSet<>();

// 클래스를 타입으로 사용해 나쁜 예
LinkedHashSet<Son> sonSet = new LinkedHashSet<>();

다만 주변 코드가 이 기능에 기대어 동작한다면 새로운 클래스도 반드시 같은 기능을 제공해야 한다

구현타입을 인터페이스로하면 원래 것보다 성능이 좋거나 신기능을 제공하기 쉬워진다

적합한 인터페이스가 없다면 클래서로 참조해야 한다

적합한 인터페이스가 없는 경우

  1. String, BigInteger
  2. 클래스 기반으로 작성된 프레임워크가 제공하는 객체들
  3. 인터페이스에는 없는 특별한 메서드를 제공하는 클래스

리플렉션보다는 인터페이스를 사용하라

java.lang.reflect를 이용하면 프로그램에서 임의의 클래스에 접근하는 것이 가능

리플렉션을 이용하면 컴파일 당시에 존재하지 않던 클래스도 이용할 수 있다

리플렉션 단점

  1. 컴파일타임 타입 검사가 주는 이점을 하나도 누릴 수 없다.
  2. 코드가 지저분하고 장황해진다
  3. 성능이 떨어진다

리플렉션은 인스턴스 생성에만 쓰고, 이렇게 만든 인스턴스는 인터페이스나 상위 클래스로 참조해 사용해야 한다

네이티브 메서드는 신중히 사용하라

네이티브 메서드의 주요 쓰임

  1. 레지스트리 같은 플랫폼 특화 기능을 사용
  2. 네이티브 코드로 작성된 기존 라이브러리를 사용
  3. 성능 개선을 목적으로 성능에 결정적인 영향을 주는 영역만 따로 네이티브 언어로 작성한다

성능을 개선할 목적으로 네이티브 메서드를 사용하는 것은 권장하지 않는다

네이티브 메서드의 단점

  1. 메모리 훼손 오류로 부터 안전하지 않다
  2. 자바 플렛폼을 많이 타서 이식성이 낮다
  3. 디버깅이 어려움
  4. 주의해 사용하지 않으면 성능이 느려질 수 있다
  5. 가비지 컬랙터가 추적하지 못함
  6. 자바 코드와 네이티브 코드의 경계를 넘나들 때마다 비용도 추가
  7. 네이티브 메서드와 자바 코드 사이의 접착 코드를 작성해야 되는데 이도 쉽지 않음

최적화는 신중히 하라

빠른 프로그램보다는 좋은 프로그램을 작성해야 한다

성능을 제한하는 설계를 피해야 한다

API를 설계할 때 성능에 주는 영향을 고려하라

성능을 위해 API를 왜곡하는 건 매우 안좋다

성능 모델이 덜 정교한 자바에서는 최적화 시도 전후의 성능 측정이 중요한다

프로그래머가 작성하는 코드와 CPU에서 수행하는 명령 사이의 추상화 격차가 커서 최적화로 인한 성능 변화를 예측하기 힘들다

일반적으로 통용되는 명명 규칙을 따르라

표준 명명 규칙을 잘 익혀 자연스럽게 사용하자

profile
Keep going하는 개발자

0개의 댓글