9장. 일반적인 프로그래밍 원칙

Red Culture·2021년 6월 4일
0
  • 아이템57: 지역변수의 범위를 최소화하라
    -가장 강력한 기법은 가장 처음 쓰일 때 선언하는 것이다.
    -거의 모든 지역변수는 선언과 동시에 초기화해야 한다. (try-catch는 이 규칙에서 제외)
    -for 형태든 for-each 형태든, 반복문에서는 반복 변수의 범위가 반복문의 몸체, 그리고 for 키워드와 몸체 사이의 괄호 안으로 제한되끼 때문에 반복 변수 값을 반복문이 종료된 뒤에도 써야 하는 상황이 아니라면 while문보다는 for문을 쓰는 편이 낫다.
    -메서드를 작게 유지하고 한 가지 기능에 집중하는 것이 좋다.

  • 아이템58: 전통적인 for문보다는 for-each문을 사용하라
    -for-each문은 반복자와 인덱스 변수를 사용하지 않으니 코드가 깔끔해지고 오류가 날 일도 없다.
    -for-each문을 사용할 수 없는 상황이 세 가지있다.
    1) 파괴적인 필터링: 컬렉션을 순회하면서 선택된 원소를 제거해야 한다면 반복자의 remove 메서드를 호출해야 하는데 자바8부터는 Collection의 removeIf 메서드를 사용해 컬렉션을 명시적으로 순회하는 일을 피할 수 있다.
    2) 변형: 리스트나 배열을 순회하면서 그 원소의 값 일부 혹은 전체를 교체해야 한다면 리스트의 반복자나 배열의 인덱스를 사용해야 한다.
    3) 병렬 반복: 여러 컬렉션을 병렬로 순회해야 한다면 각각의 반복자와 인덱스 변수를 사용해 엄격하고 명시적으로 제어해야 한다.

  • 아이템59: 라이브러리를 익히고 사용하라
    -자바7부터는 Random을 더 이상 사용하지 않는 게 좋다. ThreadLocalRandom으로 대체하면 대부분 잘 작동한다. 포크-조인 풀이나 병렬 스트림에서는 SpittableRandom을 사용하라.

  • 아이템60: 정확한 답이 필요하다면 float와 double은 피하라
    -코딩 시 불편함이나 성능 저하를 신경 쓰지 않겠다면 BigDecimal을 사용하라. BigDecimal이 제공하는 여덞 가지 반올림 모드를 이용하여 반올림을 완벽히 제어할 수 있다.
    -성능이 중요하고 소수점을 직접 추적할 수 있고 숫자가 너무 크지 않다면 int나 long을 사용하라.
    -숫자를 아홉 자리 십진수로 표현할 수 있다면 int를 사용하고, 열여덟 자리 십진수로 표현할 수 있다면 long을 사용하라. (열여덟 자리를 넘어가면 BigDecimal을 사용해야한다.)

  • 아이템61: 박싱된 기본 타입보다는 기본 타입을 사용하라
    -기본 타입과 박싱된 기본 타입의 주된 차이는 3가지이다.
    1) 기본 타입은 값만 가지고 있으나, 박싱된 기본 타입은 값에 더해 식별성을 갖는다.
    2) 기본 타입의 값은 언제나 유효하나, 박싱된 값은 null을 가질 수 있다.
    3) 기본 타입이 박싱된 기본 타입보다 시간과 메모리 사용면에서 더 효율적이다.
    -기본 타입을 다루는 비교자가 필요하다면 Comparator.naturalOrder()를 사용하자.
    -비교자를 직접 만들면 비교자 생성 메서드나 기본 타입을 받는 정적 compare 메서드를 사용해야 한다.
    -기본 타입과 박싱된 기본 타입을 혼용한 연산에서는 박싱된 기본 타입의 박싱이 자동으로 풀린다
    -그렇다면 박싱된 기본 타입은 언제 써야 할까?
    1) 컬렉션의 원소, 키 값으로 쓴다. 컬렉션은 기본 타입을 담을 수 없으므로 어쩔 수 없이 박싱된 기본 타입을 써야만 한다.
    2) 매개변수화 타입이나 매개변수화 메서드의 타입 매개변수로는 박싱된 기본 타입을 써야한다.
    3) 리플렉션을 통해 메서드를 호출할 때도 박싱된 기본 타입을 사용해야한다.

  • 아이템62: 다른 타입이 적절하다면 문자열 사용을 피하라
    -문자열은 다른 값 타입을 대신하기에 적합하지 않다.
    -문자열은 혼합 타입을 대신하기에 적합하지 않다.
    -문자열은 권한을 표현하기에 적합하지 않다.

  • 아이템63: 문자열 연결은 느리니 주의하라
    -많은 문자열을 연결할 때는 문자열 연결 연산자(+)를 피하자. 대신 StringBuilder의 append 메서드를 사용하라.

  • 아이템64: 객체는 인터페이스를 사용해 참조하라
    -적합한 인터페이스만 있다면 매개변수뿐 아니라 반환값, 변수, 필드를 전부 인터페이스 타입으로 선언하라.
    -> Set sonSet = new LinkedHashSet<>();
    (나쁜 예: LinkedHashSet sonSet = new LinkedHashSet<>();)
    -적합한 인터페이스의 부류: String, BigInteger 같은 값 클래스 / 클래스 기반으로 작성된 프레임워크가 제공하는 객체들 / 인터페이스에 없는 특별한 메서드를 제공하는 클래스(ex) PriorityQueu 클래스는 Queue 인터페이스에 없는 comparator 메서드를 제공함)
    -적합한 인터페이스가 없다면 클래스의 계층구조 중 필요한 기능을 만족하는 가장 덜 구체적인(상위의) 클래스를 타입으로 사용하자.

  • 아이템65: 리플렉션보다는 인터페이스를 사용하라
    -리플렉션 기능을(java.lang.reflect) 이용하면 프로그램에서 임의의 클래스에 접근할 수 있다. 나아가 Constructor, Method, Field 인스턴스를 이용해 각각에 연결된 실제 생성자, 메서드, 필드를 조작할 수도 있다. 하지만, 단점이 있다.
    1) 컴파일타임 타입 검사가 주는 이점을 하나도 누릴 수 없다. (리플렉션을 써서 존재하지 않는 혹은 접근할 수 없는 메서드를 호출하려 시도하면 런타임 오류가 발생한다.)
    2) 리플렉션을 이용하면 코드가 지저분하고 장황해진다.
    3) 성능이 떨어진다.
    -> 위와 같은 이유로 리플렉션은 아주 제한된 형태로만 사용해야 그 단점을 피하고 이점만 취할 수 있다. 인스턴스 생성에만 쓰고, 이렇게 만든 인스턴스는 인터페이스나 상위 클래스로 참조해 사용하자. 리플렉션은 런타임에 존재하지 않을 수도 있는 다른 클래스, 메서드, 필드와의 의존성을 관리할 때 적합하다. 버전이 여러 개 존재하는 외부 패키지를 다룰 때 유용하다.

  • 아이템66: 네이티브 메서드는 신중히 사용하라
    -네이티브 메서드: C나 C++같은 네이티브 프로그래밍 언어로 작성한 메서드
    -주요 쓰임은 레지스트리 같은 플랫폼 특화 기능, 기존 라이브러리를 사용한 레거시 라이브러리, 성능 개선을 목적으로 성능에 결정적인 영향을 주는 영역만 따로 작성
    -성능을 개선할 목적으로 네이티브 메서드를 사용하는 것은 거의 권장하지 않는다.
    -메모리 훼손 오류로부터 안전하지 않고, 이식성이 낮고, 디버깅이 어렵다.
    -가비지 컬렉터가 네이티브 메모리는 자동 회수하지 못하고, 심지어 추적조차 할 수 없다.

  • 아이템67: 최적화는 신중하라
    -빠른 프로그램을 작성하려 안달하지 말자. 좋은 프로그램을 작성하다 보면 성능은 따라 오게 마련이다.
    -성능을 제한하는 설계를 피하라.
    -API를 설계할 때 성능에 주는 영향을 고려하라.

  • 아이템68: 일반적으로 통용되는 명명 규칙을 따르라
    -객체를 생성할 수 있는 클래스의 이름은 보통 단수 명사나 명사구를 사용 (Thread, PriorityQueue, ChessPiece 등)
    -객체를 생성할 수 없는 클래스의 이름은 보통 복수형 명사 (Collections, Collectors)

profile
자기 개발, 학습 정리를 위한 블로그

0개의 댓글