7장. 프로그래밍 일반

항목 29 : 지역변수의 유효범위를 최소화하라

이유 : 가독성향상(유지보수편의), 오류발생가능성감소 (p.188.1~5)

  • 지역변수의 유효범위를 최소화하는 가장 좋은 방법은 쓰기 바로 전에 선언.
  • 대부분의 지역변수는 선언과 함께 초기화 (예외: try-catch구문) (p188:8~)
    try블록이 끝난 후 에 변수를 써야하는 경우 (항목 35의 예제)
  • 반복문의 경우 반복변수의 선언으로 유효범위를 정확하게 필요한 범위로 제한할 수 있다.(필요한 부분:for구분의 블록, 반복변수의 초기화, 조건검사, 변수값의 증감)
    반복변수를 반복문안에 쓴다면, for반복문을 쓴다.(copy&paste시 오류를 줄임)

 Iterator i = c.iterator();
 while(i.hasNext()){
  doSomething(i.next());
 } ....
Iterator i2 = c2.iterator();
 while(i.hasNext()){ //버그!
  doSomething(i2.next());
 }
// 두번째 반복문의 실행시에도 i는 유효하므로 문제없이 컴파일, 동작함으로 인해 찾기어려운 버그
//그러나 for문의 경우 컴파일시 오류

 for(Iterator i = c.iterator();i.hasNext();){
  doSomething(i.next());
 } ....

 for(Iterator i2 = c2.iterator();i.hasNext();){  //the symbol i cannot be resolved 발생
  doSomething(i2.next());
 }

  • and

 for(int i=0;i<list.size();i++){
   doSomething(list.get(i)); //매번 size()를 호출한다.
 }
  
 //임의접근(random access)리스트를 순회하는 구현패턴. 임의접근에만 사용
 for(int i=0, n=list.size(); i<n;i++){
   doSomething(list.get(i));
 }
//두번째 반복변수 n을 쓰는 것에 유의
// 이변수를 쓰지 않을 경우, 매번 size메소드를 호출하여 성능 저하

– random access : 비순차적 접근, 어떤 데이터를 기억 장소에 써 넣거나 거기에서 읽어 낼 때에, 기억 장소에 관계없이 동일한 접근 시간이 걸리는 접근 방식. ≒랜덤 액세스- 임의 접근.
순차적접근에 사용할 경우, O(n2)알고리즘의 양상을 보임(성능저하) <그림>
O(n2) - 이중 루프 내에서 입력 자료를 처리하는 경우에 나타남

  • 한 메소드는 한가지 작업만 처리하도록 가능하면 작게.-두가지 이상의 작업을 하나의 메소드에서 처리할 경우, 하나의 작업에 썼던 지역변수가 다른 작업을 처리할때까지 유효.

항목 30 : 라이브러리를 배우고 익혀서 써라

  • 표준 라이브러리를 쓰면, 이것을 작성한 전문가의 지식과 먼저 써본 사람들의 경험까지 얻을 수 있다.
    (p 192~) 난수발생의 예 (Random.nextInt(int) 사용)
  • java.lang.util, java.lang.io, 컬렉션프레임워크 등 주요기능 이해
    ex) ① 문자열 벡터를 알파벳 순으로 정렬 : Collections.sort(v); 대소문자구분없이 정렬:Collections.sort(v, String.CASE_INSENSITIVE_ORDER);
    ② 모든 배열이 구성요소출력 : System.out.println(Arrays.asList(a));
    ③ 두개의 Hashtable 인스턴스 h1, h2에서 같은 키-값을 갖는 엔트리의 모든 키 :

import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;


public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		Hashtable h1 = new Hashtable();
		Hashtable h2 = new Hashtable();
		
		h1.put("01", "1");h1.put("02", "1");h1.put("03", "1");h1.put("04", "04");
		h2.put("01", "1");h2.put("02", "1");h2.put("03", "1");h2.put("04", "3");			
		
		Map tmp = new HashMap(h1);
		tmp.entrySet().retainAll(h2.entrySet());
		Set result = tmp.keySet();
		
		for(Iterator i = result.iterator();i.hasNext();){
			System.out.println(i.next());
		}
	}
}

항목 31 : 정확한 계산에 float이나 double 타입을 쓰지마라

  • float와 double은 과학, 공학계산용으로 매우 넓은 범위의 수에 대한 매우 정확한 근사값을 빨리 계산할 수있는 부동소수점 연산(binary floating-point arithmetic)하나, 값이 정확하지 않기 때문에 정확한 계산을 필요로 할 경우, 사용금지(ex: 금전계산 등)

(p.197~199)

항목 32 : 적절한 타입 대신 문자열을 쓰지마라

  • 문자열은 텍스트를 표현하기 위해 만든 것!
    ① 문자열로 값타입을 대신하지 마라.
    ② 문자열로 집합타입을 대신하지 마라.
    ③ 문자열로 열거타입을 대신하지 마라.
    ④ 문자열로 어떤 기능을 대신하지 마라.(ex.접근권한제어 등 p.201)

항목 33 : 성능을 떨어뜨리는 문자열 연결을 조심하라

  • n개 문제열을 연결할 때 문자열 연결 연산자를 반복해서 쓰면, 걸리는 시간은 n의 제곱에 비례한다. - String 이 불변클래스이기 때문에 생기는 문제(항목 13)
    두개의 문자열을 연결할때, 두 분자열의 내용을 모두 복사해서 새로운 문자열을 만들기 때문.

String 클래스 대신 StringBuffer(append()) 클래스 사용

항목 34 : 인터페이스 타입으로 객체를 참조하라

적절한 인터페이스타입이 있다면, 인자, 리턴값, 변수, 필드는 반드시 인터페이스타입으로 선언해야한다. - 클래스는 객체를 생성할때만 사용.

  • 유연한 프로그램을 만들수 있다.
    cf) 이전에 썼던 구현체가 인터페이스의 일반계약에는 없는 특별한 기능을 제공하고 프로그램이 이 기능에 의존하고 있다면, 새로운 구현체도 이 기능을 반드시 제공해야만 한다.
    예를 들어, 어떤 프로그램이 Vector클래스가 내부에서 동기화 한다는 사실에 의존하고 있다면, Vector클래스 대신 ArrayList 클래스를 쓰면 문제가 발생할 수 있다.
  • 그럼에도 구현체를 바꿀수 있도록 하는 이유는, 새로운 구현체가 성능이 더나 을수 있고, 더 바람직한 새로운 기능을 제공할 수도 있기때문.(p.206)
  • 적절할 인터페이스타입이 없다면, 인터페이스타입이 아닌 클래스 타입으로 객체를 참조해도 괜찮으나, 필요한 기능을 제공해주는 최상위 클래스 타입을 사용하는 것이 좋다.

항목 35 : 리플렉션보다 인터페이스를 써라

  • 리플렉션은 굉장히 복잡한 시스템을 만들때 꼭 필요한 강력한 기능이지만, 많은 단점이 있다.
    컴파일시점에 발견할 수 있었던 오류들을 실행시점에 발견할 수 밖에 없다.
    생성자를 호출하면 한줄로 끝날 수있는 작업이 스무줄 이상의 코드로 늘어나게 된다.

컴파일 시점에 없는 클래스를 써야 하는 프로그램을 만들 때, 가능하면 인스턴스 생성시에만 리플랙션을 쓰고, 인스턴스에 대한 접근은 컴파일 시점에 이미 알려진
인터페이스나 상위 추상클래스를 쓰는 것이 좋다. (p.211)

항목 36 : 네이티브 메소드는 신중하게 써라

  • Java Native Interface 용도

① 레지스트리나 파일락과 같은 플랫폼 종속적인 기능에 접근할 때
② 레거시에 존재하는 데이터에 접근하기 위해 레거시 언어로 작성한 라이브러리에 접근할때
③ 성능에 민감한 부분을 네이티브 언어로 작성하여 성능을 높일 때

1.3 배포판부터 네이티브 메소드를 써서 성능을 높이는 것을 권장하지 않는다.

-java 플랫폼의 발전, JVM의 성능향상, 다양한 기능제공으로 네이티브메소드 사용 필요가 줄어듬

-단점 : 네이티브언어가 안전하지 못함(항목24)로 인해 메모리에 신경써야함. 플랫폼 종속적, 작성 난이, 가독성저하 등

항목 37 : 신중하게 최적화하라

  • 빠른 프로그램보다는 좋은 프로그램을 만들기위해노력하라.

항목 38 : 일반 작명규칙을 지켜라

http://java.sun.com/docs/books/jls/third_edition/html/names.html#6.8

문서에 대하여