2014년 5월 6일 화요일

컴파일러가 안 가르쳐 주지?



프로그램을 제대로 개발하려면 너무 세세히 신경쓸 일이 많다. 그러니까 대충 가정하며 하게 된다. 이거야 당연히 이렇게 될 테지 하는 거 말이다. 그 중에 모든 사람이 저지르는 잘못이 변수를 당연히 null이 아니라고 가정하고 사용하는 것이다. 누구의 코드를 봐도 이런 잘못을 쉽게 발견할 수 있다.



예를 들어 보자.
int[] priceArray = getPriceList();
int sum = 0;
for (int i=0; i< priceArray.length. i++) {
	sum = sum + priceArray[i]; 
}

이 얼마나 간단한 코드인가. 보통 경우 문제없이 구동 될 것이다. 아마 운이 좋으면 평생 뭐가 잘못된 지를 발견 못할지도 모른다. 문제는 priceArray가 null 포인터가 될지도 모른다는 것이다. Null 포인터가 되면 priceArray.length 에서 NullPointException이 발생하고 프로그램이 작동 중지될 것이다. 왜 이것이 컴파일은 문제없이 되고 구동시에만 문제가 되는지 모르는 사람도 많다. 보통은 Exception이 발생하는 경우에 처리하는 코드가 없으면 컴파일러가 친절하게 가르쳐 주지 않던가? 처리하는 코드를 추가하라고.



이것은 소위 RuntimeException 이라고 컴파일할 당시에는 오류를 발견할 수 없는 경우다. 실제 구동 할때만 발생할 수 있는 경우다. 아직도 Exception을 사용해 본적이 없거나 RuntimeException이 무엇인지 몰랐다면 지금 당장 책을 보고 배우라. 당신은 지금까지 엉터리 프로그램을 하고 있었던 것이다. NullPointException 이외에도 ArrayIndexOutOfBoundsException 같은 것도 흔히 보는 RuntimeException이다.



여러분이 프로그램을 구동하다가 NullPointException 이나 ArrayIndexOutOfBoundsException 이 한번이라도 발생했다면 믿을 수 없는 코드이다. 당장 가서 코드를 고쳐야 한다. 발생한 곳만 고치는 것이 아니라 전체 소스코드를 처음부터 끝까지 한줄 한줄 코드를 보면서 비슷한 오류를 범했는지 확인해야 한다.



그러면 어떻게 해야 옳은 프로그램인가? 여러가지 방법이 있는데 두 가지만 보여주겠다.



(첫째 방법)
int[] priceArray = getPriceList();
int sum = 0;
if (priceArray != null) {
    for (int i=0; i< priceArray.length. i++) {
        sum = sum + priceArray[i]; 
    }
}



(둘째 방법)
int[] priceArray = getPriceList();
int sum = 0;
try {
    for (int i=0; i< priceArray.length. i++) {
	sum = sum + priceArray[i]; 
    }
} catch (NullPointException e) {
    e.printStackTrace();
    // 어떻게 처리할지 코드를 여기에 삽입한다.
}

여기서도 역시 되는 기능보다는 항상 잘못될 경우를 처리하는데 더 신경을 곤두세우고 있다는 것을 명심하기 바란다. 되게 만드는 것보다는 안되는 경우를 처리하는데 몇배의 시간이 들어간다.

댓글 없음: