규칙 54 - 네이티브 메서드는 신중하게 사용하라
규칙 55 - 신중하게 최적화하라
규칙 56 - 일반적으로 통용되는 작명 관습을 따르라


아래 책를 참고하여 학습한 내용을 정리/기록한 포스트입니다. 자세한 내용은 책을 참고하시기 바라며, 문제가 있을 경우 연락 부탁드립니다.


  • 조슈아 블로크, 이병준(옮긴이), Effective Java, 2판, 인사이트, 2015.



54. 네이티브 메서드는 신중하게 사용하라

JNI(Java native interface): C나 C++ 등의 네이티브 프로그래밍 언어로 작성된 네이티브 메서드를 호출하는 데 이용되는 기능.

전통적으로 네이티브 메서드는 세 가지 용도로 쓰였다.

  1. 레지스트리나 파일 락 같은 특정 플랫폼에 고유한 기능 이용 가능
  2. 이미 구현되어 있는 라이브러리 이용 가능
  3. 성능이 중요한 부분의 처리를 네이티브 언어로 처리 가능

하지만 자바 플렛폼이 발전하면서 자바로 대체 가능

  1. java.util.prefs를 이용하면 레지스트리 기능 이용 가능(java 1.4)
  2. java.awt.SystemTray를 사용하면 시스템 트레이 영역 이용 가능(java 1.6)

결론

네이티브 메서드를 통해 성능을 개선하는 것은 추천하고 싶지 않다.

  • 자바 발전에 따라 그에 필적하는 성능을 낸다
  • 네이티브 언어는 안전하지 않다(규칙 39). 메모리 훼손 문제로부터 자유로울 수 없다
  • 종속적이다
  • 디버깅이 어렵다

55. 신중하게 최적화하라

최적화 관련 격언(자바 언어가 나오기 20년 전에 나온 것들)

맹목적인 어리석음(blind stupidity)을 비롯한 다른 어떤 이유보다도, 효율성이라는 이름으로 저질러지는 죄악이 더 많다(효율성을 반드시 성취하는 것도 아니면서 말이다).

윌리엄 울프(William A. Wulf)

작은 효율성(small effciency)에 대해서는, 말하자면 97% 정도에 대해서는, 잊어버려라. 섣부른 최적화(premature optimization)는 모든 악의 근원이다.

도널드 커누스(Donald E. Knuth)

최적화를 할 때는 아래의 두 규칙을 따르라.
규칙 1: 하지 마라.
규칙 2: (전문가들만 따를 것)아직은 하지 마라 - 완벽히 명료한, 최적화되지 않은 해답을 얻을 때까지는.

M.A. 잭슨(M. A. Jackson)

핵심

  • 빠른 프로그램이 아닌, 좋은 프로그램을 만들려 노력하라.

    좋은 프로그램은 정보 은닉 원칙을 지킨다. 따라서 그 설계는 시스템의 다른 부분에는 영향을 주지 않으면서 독립적으로 변경될 수 있다.

  • 설계를 할 때는 성능을 제약할 가능성이 있는 결정들은 피하라.

    고치기 가장 까다로운 부분이 모듈 간 상호작용이나 외부와의 상호작용을 명시하는 부분. API, 통신 프로토콜 등

  • API를 설계할 때 내리는 결정들이 성능에 어떤 영향을 끼칠지를 생각하라.

    • 변경 가능한 자료형을 만들면 쓸데없이 방어적 복사를 많이 할 수 있다.(규칙 39)
    • compotision이 적절한 곳에 inheritance를 하지 말아라(규칙 16).
    • 인터페이스가 적절한 곳에 구현 자료형을 사용하지 말아라(규칙 52).
  • 좋은 성능을 내기 위해 API를 급진적으로 바꾸는 것은 바람직하지 않다.

  • 최적화를 시도할 때마다, 전후 성능을 측정하고 비교하라.
    • 자바는 강력한 성능 모델이 없으며, 다양한 환경, 설정에 따라 성능이 다르다.

56. 일반적으로 통용되는 작명 관습을 따르라

The Java Language Specification[JSL, 6.8]에도 언급되어 있듯이, 작명 관습이 잘 정립되어 있다.

철자

Package

  • 알파벳 소문자
  • 숫자는 거의 사용하지 않음
  • 인터넷 도메인으로 시작(예외적으로, 표준 라이브러리와 그 옵션 패키지 명은 java와 javax로 시작)
  • 패키지명 컴포넌트는 짧아야하며, 보통 8문자 이하도 만듦(하나의 단어 또는 약어)
  • 의미가 확실한 약어 활용(e.g. utilities -> util)

Enum, Annotation, Class, Interface

  • 하나 이상의 단어
  • 첫글자 대문자
  • 널리 쓰는 약어(e.g. max, min)외에 다른 약어는 사용을 피함

Method, Field

  • Class와 규칙 같음, 다만 첫글자 소문자
  • 상수는 대문자와 단어 사이에 _

Local variable

  • Filed와 동일
  • 약어 허용

Generic type

  • 대문자
  • 임의 자료형: T
  • 컬렉션의 요소 자료형: E
  • 맵의 키와 값: K, ‘V’
  • 예외: X
  • 임의 자료형이 연속되는 경우: T, U, V 혹은 T1, T2, T3

문법

Package

  • 굳이 없음

Enum, Class

  • 단수형의 명사, 명사구

Interface

  • Class와 동일
  • -able, -ible 같은 형용사격 어미가 붙기도 함(e.g. Runnable, Iterable)

Annotation

  • 명사, 동사, 전치사, 형용사 어느것이나 널리 사용

Method

  • 동사, 동사구(e.g. append)
  • boolean을 반환하는 메서드는 보통 is-, (드물게)has-(e.g. isEmpty, isDigit)
  • 기능이나 객체 속성을 반환하는 메서드는 명사, 명사구, get-(e.g. size(), hasCode)
  • Bean 클래스에 속한 메서드는 getter(get-), setter(set-)
  • 객체의 자료형을 반환하거나 다른 자료형의 독립적 객체는 반환하는 경우 toType(e.g. toString, toArray)
  • 인자로 전달받은 객체와 다른 다료형의 뷰(view) 객체를 반환하는 메서드의 경우 asType(e.g. asList)
  • 호출 대상 각체와 동일한 기본 자료형 값을 반환하는 메서드의 경우 typeValue(e.g. intValue)
  • 정적 팩터리 메서드는 valueOf, of, getInstance, newInstance, getType, newType