상수
는 변하지 않는 수를 의미합니다.
상수를 자바에서는 final 이라는 예약어를 사용하여 선언합니다.
개념은 사실 여기서 끝이다. 하지만, 그냥 변수를 사용해도 크게 문제가 되지 않을 것 같은데 왜 굳이 사용하는 것일까요?
굳이 상수를 선언하는 이유가 무엇일까?
- 가독성 측면
값이 변경되지 않는 다는 것을 미리 공지하여, 읽음에 있어 고려할 것을 줄여 가독성을 향상시킬 수 있습니다.- 안정성
바뀌지 말아야 할 앖을 선언 시점에 명시함으로서 실수로 변경하지 않도록 방지합니다.- 최적화 기회 제공
일반적으로 변수의 경우 메모리에서 현재 값을 매번 Load해야 하지만, 상수는 값이 변경되지 않으므로 컴파일러의 재량에 따라 미리 값을 최초 1회 Load 이후 캐싱해 놓는단지 여러 최적화 기회가 열리게 됩니다.
또한, 멀티쓰레드 환경에서 변수는 thread-safe를 신경써야 하는 대상인 반면, 상수는 값이 변경되지 않으므로 그렇지 않습니다.
⚡ 스레드 안전(Thread-Safe) ⚡
스레드 안전은 멀티 스레드 프로그래밍에서 일반적으로 어떤 함수나 변수, 혹은 객체가 여러 스레드로부터 동시에 접근이 이루어져도 프로그램의 실행에 문제가 없음을 뜻합니다.
여기서 변수는 신경 써야 하는 이유는 같은 변수가 동시에 여러 스레드에서 값을 변경하려고 할 때 문제가 발생할 경우가 있기 때문입니다.
매직 넘버(magic number)
, 매직 리터럴(magic literal)
이란 소스 코드에서 의미를 가진 숫자나 문자를 그대로 표현한 것을 말합니다.
이러한 표현은 소스 코드를 읽기 어렵게 만듭니다. 상수로 선언되어 있지 않은 숫자, 문자열은 무엇을 의미하는지 확신을 할 수 없게 만듭니다. 이러한 의미를 파악하기 위해 해당 클래스와 흐름을 이해하기 위해 많은 시간을 요구합니다.
상수(static final)
로 선언하게 되면 이러한 값들에게 이름이 부여된다. 이름을 통하여 의미와 역할을 확실히 전달할 수 있다.
아래 예시 코드를 통해서 살펴봅시다.
public class Foo {
public void setPassword(String password) {
// don't do this
if (password.length() > 7) {
throw new InvalidArgumentException("password");
}
}
}
해당 코드에서 7이라는 숫자가 무엇을 의미하는지 바로 알기가 힘듭니다.
따라서 아래와 같이 코드를 써줍니다.
public class Foo {
public static final int MAX_PASSWORD_SIZE = 7;
public void setPassword(String password) {
if (password.length() > MAX_PASSWORD_SIZE) {
throw new InvalidArgumentException("password");
}
}
}
이러한 리팩토링은 코드의 가독성이 향상되고 유지 관리가 더 쉽게 만들 수 있습니다.
Reference