해당 포스트는 "Effective Java" 책의 내용을 요약한 것이다.



※ 지역 변수의 유효범위를 최소화해라

: 지역변수를 처음으로 사용하는 곳에서 선언하도록 하는 게 좋다. 또한 초기값이 포함되어 있으면 좋다. while 문보다는 for문을 쓰는 게 좋다. for문 안에서 반복문마다 생성되는 게 아닌 한 번만 생성된다면 다음과 같이 해라.

for(int i=0, n=a.length; i < n ; i++)

또한 지역 변수의 유효 범위를 최소화하기 위해 메서드의 크기를 줄이고 하나의 기능에 집중해라. 두 가지 서로 다른 기능을 하나의 메서드 안에 두지 마라.


※ for문 보다는 for-each 문을 사용하라

: for-each 구문을 사용하면 for문보다 오류 가능성을 낮출 수 있다. 다음의 예를 보자.

enum Suit { CLUB, DIAMOND, HEART, SPADE }
enum Rank { ACE, DEUCE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING }

Collection<Suit> suits = Arrays.asList(Suit.values());
Collection<Rank> ranks = Arrays.asList(Rank.values());
List<Card> deck = new ArrayList<Card>();

for (Iterator<Suit> i = suits.iterator(); i.hasNext(); )
    for (Iterator<Rank> j = ranks.iterator(); j.hasNext(); )
        deck.add(new Card(i.next(), j.next()));

위 코드에는 하나의 에러가 있다. 중첩 for문 안쪽 i.next()가 안쪽 for문 바깥으로 나와야 한다. for-each문을 사용할 경우 이런 오류 가능성을 간편하게 막을 수 있다.

for(Suit suit : suits)
	for(Rank rank : ranks)
		deck.add(new Card(suit, rank));

for-each문은 Iterable 인터페이스를 구현하면 우리가 만든 클래스에서도 사용이 가능하다. 

for-each는 버그 가능성도 적고 명료하며 성능도 for문과 거의 비슷하다. 가능하면 for-each를 사용하는 게 좋다. 하지만 for-each를 사용할 수 없는 경우가 있는 데 다음과 같다.

1. 필터링 : 컬렉션을 순회하다가 특정 원소를 삭제할 필요가 있을 때(반복자가 없기 때문)

2. 변환 : 리스트나 배열을 순회하다가 그 원소 가운데 일부 또는 전부를 변경해야 할 때



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

: float와 double은 오차범위가 존재한다. 따라서 돈과 같이 정확한 계산이 필요한 데는 float와 double은 절대 사용하면 안 된다. 소수점 이하의 처리가 자동으로 되고 사용하기 불편하도 되며 성능이 조금 떨어져도 상관 없으면 BigDecimal을 써도 된다. 성능이 중요하고 소수점 처리를 직접 할 수 있으며 계산할 수가 심하게 크지 않을 때는 int나 long을 써라. 관계된 수치가 십진수 아홉 개 이하로 표현이 가능하면 int, 18개 이하로 표현 가능하면 long을 써라. 그 이상은 BigDecimal을 써야 한다.



- 가능하면 기본 자료형을 사용해라. 더 단순하고 빠르다. 객체화된 기본 자료형을 사용하면 "==" 연산을 할 때 주의하라. 


- 더 좋은 자료형이 있거나 만들 수 있을 때는 객체를 문자열로 표현하는 것은 피하라.


- 문자열을 +연산자로 더할 때는 String 객체를 사용하는 걸 피하라. 대신 StringBuilder의 append 메서드를 사용하라.


- 객체를 참조할 때는 할 수있으면 인터페이스를 사용해라. 단 인터페이스를 구현한 클래스에서 추가적인 기능이 있을 시에는 인터페이스 사용을 못 한다.

List<String> strs = new Vector<String>(); 
//인터페이스를 자료형으로 사용하는 바람직한 예

Vector<String> strs = new Vector<String>();
//클래스를 자료형으로 사용하는 나쁜 예

만약 인터페이스를 자료형으로 했을 경우 Vector을 나중에 ArrayList로 바꿔야 할 때 바로 바꿀 수 있다. 


- 빠른 프로그램이 아닌 좋은 프로그램, 좋은 구조를 갖춘 프로그램을 만들어라. 시스템의 구현을 끝냈다면 프로파일링 도구를 활용해 성능을 측정하고 최적화해라. 측정하는 데 제일 먼저 해야 할 일은 구현에 쓰인 알고리즘을 검토하는 것이다. 아무리 최적화를 하더라도 알고리즘을 잘못 골랐다면 성능을 만회할 수 없다.

+ Recent posts