관리 메뉴

드럼치는 프로그래머

[JAVA] 자바의 final 키워드의 용도 본문

★─Programing/☆─JAVA

[JAVA] 자바의 final 키워드의 용도

드럼치는한동이 2007. 10. 29. 11:17

final 키워드는 대개 정적인 방식으로 많이 쓰입니다. 예를 들어 클래스 상수로 쓰이거나, 클래스의 상속이나 메소드 재정의(overriding)을 막기 위해서 자주 사용되죠.

상대적으로 잘 쓰이지 않지만, 초기화 이후에 값을 바꿀 수 없는 변수를 만드는 동적인 용도로도 사용이 가능합니다. 자바 언어 레퍼런스를 보면 다음과 같이 내용이 있습니다:

A variable can be declared final. A final variable may only be assigned to once. It is a compile time error if a final variable is assigned to unless it is definitely unassigned immediately prior to the assignment.

C나 C++에 const라는 키워드가 있는데 변수에 대해서는 final보다 const가 더 적절한 이름이라고 생각합니다. 하지만, 클래스나 메소드 정의에 부여하는 경우는 final이 아주 좋다고 생각합니다.

배열을 인자로 받아서 합계를 내는 함수가 있다고 해보죠.

int sum(int[] a) {
  int result = 0;
  for (int i : a)
       result += i;
  return result;
}

이 경우 어떤 이유에서건 아래와 같이 구현된다면 해당 메소드를 사용자 입장에서는 의도하지 않은 결과를 접하게 될 가능성이 높습니다.

int sum(int[] a) {
 int[] others = {-1, -2, -3};
 a = others;
 int result = 0;
 for (int i : a)
  result += i;
 return result;
}

간단한 예를 통해서 보면 완전히 어리섞은 구현이긴 합니다. 하지만, 테스트가 없이 장문의 타이핑을 하는 환경에서는 이와 유사한 일이 일어나지 말라는 법은 없습니다.

int sum(final int[] a) {
  int result = 0;
  for (int i : a)
       result += i;
  return result;
}

이와 같이 정의해주면 적어도 a에 새로운 할당을 시도할 수 없게 됩니다.

3 + 4 = ?

위와 같이 더하기라는 연산을 할 때 피 연산자인 3과 4는 변하지 않습니다. 3과 4가 변한다면 사람들은 위험해서(?) 덧셈을 하지 않겠죠. :)

sum()에 인자로 제공해주는 것은 피연산자와 같습니다. 의미적으로 상수가 전달되어야 하는 경우라고 할 수 있죠. 이럴 때 final을 붙여주면 보다 의미가 명확해질 수 있습니다.

아래와 같은 구문에 왜 final을 쓰면 안되느냐는 질문을 받은 일이 있습니다.

int sum(int[] a) {
  final int result = 0;
  for (int i : a)
       result += i;
  return result;
}

자칫 범하기 쉬운 오류지만, result라는 변수의 용처를 명확하게 정립해보면 논리적인 오류임을 알 수 있습니다. result는 말 그대로 임시 저장소입니다. 지역 변수(local variable)은 임시(temp/temporary) 변수라고 하는데 딱 어울리는 용도로 사용한 것이죠.

세로 타원으로 그린 것이 for 문의 실행시의 논리적인 영역을 나타냅니다. 문맥(context)이라고 할 수도 있겠죠.  반복이 진행되면서 우측으로 이동하기 때문에 배열의 요소들의 이전 값을 기억하기 위해서는 별도의 저장소가 요구됩니다. 어떤 프로그래밍 언어를 배우거나 초기에 익히는 것이지만, 논리적으로 이러한 그림을 머리속에 그릴 수 있다면 더욱 복잡한 경우를 포용할 때 매우 유리합니다.

위와 같은 경우 a[0]의 값이 temp에 들어가 있어야 하고, 반복이 한 차례 더 수행되면 temp 값에 a[1]을 더한 값이 다시 할당되어져야 하니 final로 정의하는 것은 실수죠.
Comments