Skip to main content

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

지역변수, 제어구조, 라이브러리, 데이터 타입, 리플렉션, 네이티브 메서드과 같은 자바의 기본을 다루는 챕터

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

item 57

  • item 15와 마찬가지로 클래스와 멤버의 접근 권한을 최소화하라는 취지와 비슷하다.

  • 지역 변수는 가장 처음 쓰일 때 선언하자

  • 사용하려면 멀었는데 미리 선언부터 해버리면 코드 자체가 어수선해진다.

  • 모든 지역변수는 선언과 동시에 초기화하자

  • while문 보다는 가급적 for문을 사용하자

  • 지역변수 범위를 최소화하기 위해 메서드를 작게 유지하고 한 가지 기능에 집중시키자

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

item 58

  • for-each문의 정식 이름은 향상된 for 문(enhanced for statement)이다.

  • 반복자와 인덱스를 사용하지 않으니 코드도 깔끔하고 오류도 없다

  • 아름다운 for-each이지만 다음 세 가지 경우에는 사용 할 수 없다.

for-each를 사용할 수 없는 세가지 경우#

파괴적인 필터링 (destructive filtering)#

  • 컬렉션을 순회하며 선택된 원소를 제거하는 경우

변형 (transforming)#

  • 리스트나 배열을 순회하면서 원소의 값 일부 또는 전체를 변경해야하는 경우

병렬 반복 (parallel Iteration)#

  • 여러 컬렉션을 병렬로 순회해야한다면 이 역시도 for-each 사용에 적합하지 않다.

결론#

  • for-each는 전통 for문과 비교해도 성능 저하도 없는데다가 유연하고 버그도 예방해준다. (짱짱맨)

  • 가능하면 모든 곳에서 for-each를 사용하도록 하자

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

item 59

  • 이번 장은 제목만 봐도 좀 띠용하다. 당연한 말씀을..

  • 표준 라이브러리를 사용하면 검증된 기능을 사용할 수 있다. 이미 우리가 했어야할 수 많은 테스트와 검증을 거쳐 개발된 것이므로 믿고 사용할 수 있다.

  • 자바에서 제공하는 표준 라이브러리들에 대해서 잘 이해하고 사용하도록 하자

요약#

  • 바퀴의 재발명은 금지

  • 앵간한건 다 라이브러리로 개발되어있으니까 깃허브를 잘 뒤져보자

  • 오픈소스 라이브러리의 코드 퀄리티는 우리가 작성한 것 보다 훨씬 더 좋을 수 있다. 수 많은 개발자들의 손을 거쳐갔기 때문이다.

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

item 60

  • 당연한 이야기이다. floatdouble은 OS의 CPU 성능에 달려있다. 그러므로 정확하지 않을 수 있다.

  • 소수점이 크게 중요하지않다면 intlong 자료구조를 사용하고 꼭 필요하다면 BigDecimal을 고려해보자

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

item 61

  • 박싱된 기본 타입은 Integer, Double, Boolean을 의미한다

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

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

  • 즉, null 참조를 언박싱하면 NullPointerException가 발생한다는 뜻이다

  • 박싱된 기본 타입이 사용되는 경우는 컬렉션의 타입으로 사용하는 경우이고 그 외에는 가급적 기본 타입을 사용하자

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

item 62

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

  • 문자열은 열거 타입을 대신할 수 없고, 문자열은 혼합 타입을 표현하기에 적합하지 않다

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

item 63

  • 문자열 연결 연산자로 문자열 n개를 잇는 시간은 n^2에 비례한다

  • 문자열 연결이 필요한 경우라면 StringBuilder를 사용하자

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

item 64

  • 객체지향과도 맞물리는 이야기이다

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

  • 인터페이스 타입을 사용하는 습관을 길러두면 프로그램이 훨씬 유연해질 수 있다

  • 적합한 인터페이스가 없다면 클래스의 계층구조 중 필요한 기능을 만족하는 가장 덜 구체적인 클래스를 타입으로 쓰자

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

item 65

  • 리플렉션을 이용하면 컴파일 타임에 존재하지 않는 클래스도 사용이 가능하다

  • 그러나 리플렉션은 다음과 같은 단점을 갖는다

리플렉션의 단점#

  • 컴파일타임 타입 검사가 주는 이점을 누릴 수 없다

  • 리플렉션을 이용하면 코드가 지저분하고 장황해진다

  • 성능이 떨어진다

리플렉션을 쓰는 경우#

  • 아주 제한적인 형태로만 사용해야한다, 가령 스프링과 같은 프레임워크에서 메모리에 올라오지 않은 객체들을 관리할 때 사용해볼 수 있다

  • 프레임워크나 라이브러리가 아닌 우리가 코드레벨에서 리플렉션을 사용하는 경우는 가급적 없어야 한다

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

item 66

  • 자바 네이티브 인텊에ㅣ스는 자바 프로그램이 네이티브 메서드를 호출하는 기술이다

  • 여기서 네이티브 메서드란 C나 C++과 같이 네이티브 프로그래밍 언어로 제작된 메서드들을 의미한다

네이티브 메서드를 쓰는 목적#

  • 레지스트리 같은 플랫폼 특화 기능을 사용하는 경우

  • 네이티브 코드로 작성된 기존 라이브러리를 사용하는 경우

  • 성능 개선을 목적으로 성능에 결정적인 영향을 주는 영역만 따로 네이티브 언어로 개발하는 경우

네이티브 메서드의 장단점#

  • 성능을 개선할 목적으로라면 절대 쓰면 안된다

  • JVM이 많은 발전을 이뤄서 이제는 네이티브 메서드보다 순수 자바로 다시 작성한 코드의 성능이 더 좋은 경우가 생겨나고 있다

  • 네이티브 라이브러리 쪽은 다중 정밀 연산을 필두로 성능이 개선되고 있고, 다중 정밀 연산이 필요한 자바 프로그래머라면 네이티브 메서드를 사용하는 것도 고려해볼만은 하다

  • 그러나 여전히 심각한 문제들이 있는데, 가령 네이티브 메모리는 자동 회수 되지 못해서 GC의 타겟이 될 수 없다

  • 자바 코드와 네이티브 코드의 경계를 넘나들 때 마다 비용이 발생하는데

  • 그 둘을 이어붙이기 위한 접착 코드를 별도로 작성해야한다

  • 이는 귀찮은 작업인데다가 코드 가독성도 떨어진다

  • 가급적이면 쓰지말자

최적화는 신중히 하라#

item 67

  • 모든 사람이 마음 깊이 새겨야 할 최적화 격언 세 개가 있다.
(맹목적인 어리석음을 포함해) 그 어떤 핑계보다 효율서이라는 이름 아래 행해진 컴퓨팅 죄악이 더 많다 (심지어 효율을 높이지도 못하면서)
- 윌리엄 울프
(전체의 97% 정도인) 자그마한 효율성은 모두 잊자. 섣부른 최적화가 만악의 근원이다.
- 도널드 크루스
최적화를 할 때는 다음 두 규칙을 따르라
첫 번째, 하지마라
두 번째, (전문가 한정) 아직 하지 마라. 다시 말해 완전히 명백하고 최적화되지 않은 해법을 찾을 때 까지는 하지마라.
- M.A 잭슨
  • 이 격언들은 자바가 탄생하기 20년 전에 나왔고, 최적화의 어두운 진신을 이야기해준다

  • 성능 때문에 견고한 구조를 희생하지 말자

  • 빠른 프로그램보다는 좋은 프로그램을 작성하자

설계 단계에서의 고려할 부분들#

  • 성능을 제한하는 설계를 피하자

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

  • 성능을 위해 API를 왜곡하지는 말자

최적화에 관해서#

  • 최적화를 할거면 시도 전후로 성능을 측정하자

요약#

  • 빠른 프로그램을 작성하기 보다는 좋은 프로그램을 작성하려고 노력하자

  • 시스템 구현을 완료했다면 성능을 측정해보자 충분히 빠르다면 그걸로 끝이다

  • 그렇지 않다면 프로파일러를 사용해 병목이 발생하는 지점을 찾아 최적화를 진행하자

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

item 68

  • 클래스는 Camel Case

  • 메서드와 필드 이름 첫 글자는 소문자

  • 상수 필드의 경우 대문자로 쓰며 단어 사이는 밑줄로 구분

  • 지역변수에 약어를 쓰는 것은 좋다고 한다

  • 그러나 메서드 매개변수의 이름은 문서에도 등장하므로 신중히 작성하도록 하자

  • 타입 매개변수 이름은 보통 한 문자로 표현한다

    • 임의의 타입은 T, 컬렉션 원소 타입은 E, 맵의 키와 값에는 K와 V를, 예외에는 X를, 메서드의 반환 타입에는 R을 사용한다
  • 객체 타입을 바꿔서 다른 타입의 또 다른 객체를 반환하는 인스턴스 메서드의 이름은 보통 toType 형태로 짓는다. (toString, toArray 등)

  • 정적 팩터리 이름은 from, of, valueOf, instance, getInstance, newInstance, getType, newType을 흔히 쓴다

Reference#

스크린샷 2021-04-16 오후 4 24 23

이펙티브 자바 Effective Java 3/E

저자 : 조슈아 블로크

Last updated on