상수의 두 가지 측면을 구별해야합니다.
- 더 나은 유지 보수성을 위해 도입 할 때 알려진 값의 이름
- 컴파일러가 사용할 수있는 값.
그리고 관련된 세 번째 종류가 있습니다 : 값이 변하지 않는 변수, 즉 이름의 이름. 이러한 불변 변수와 상수의 차이점은 값을 결정 / 할당 / 초기화 할 때입니다. 변수는 런타임에 초기화되지만 상수 값은 개발 중에 알려져 있습니다. 개발 중에는 값을 알 수 있지만 실제로는 초기화 중에 만 생성되므로이 차이는 약간 흐릿합니다.
그러나 상수 값이 컴파일 타임에 알려진 경우 컴파일러는 해당 값으로 계산을 수행 할 수 있습니다. 예를 들어, Java 언어에는 상수 표현식 이라는 개념이 있습니다. 상수 표현식은 프리미티브 또는 문자열의 리터럴, 상수 표현식 (예 : 캐스트, 추가, 문자열 연결) 및 상수 변수의 조작으로 만 구성된 표현식입니다. [ JLS §15.28 ] 상수 변수는 final
상수 식으로 초기화 되는 변수입니다. [JLS §4.12.4] 따라서 Java의 경우 컴파일 타임 상수입니다.
public static final int X = 7;
상수 변수가 여러 컴파일 단위로 사용 된 다음 선언이 변경 될 때 이것은 흥미로워집니다. 치다:
이제이 파일들을 컴파일 할 때 B.class
바이트 코드는 상수 변수 Y = 9
이기 때문에 필드를 선언 할 것 B.Y
입니다.
그러나 A.X
변수를 다른 값 (예 X = 0
:)으로 변경하고 A.java
파일 만 다시 컴파일하면 B.Y
여전히 이전 값을 참조합니다. 이 상태 A.X = 0, B.Y = 9
는 소스 코드의 선언과 일치하지 않습니다. 행복한 디버깅!
상수가 절대 변하지 않아야한다는 의미는 아닙니다. 상수는 소스 코드에서 설명없이 나타나는 매직 숫자보다 확실히 좋습니다. 그러나 값 대중 상수는 공개 API의 일부입니다 . 이것은 Java에만 국한된 것이 아니라 별도의 컴파일 단위가있는 C ++ 및 기타 언어에서도 발생합니다. 이 값을 변경하면 모든 종속 코드를 다시 컴파일해야합니다 (예 : 클린 컴파일).
상수의 특성에 따라 개발자가 잘못 가정했을 수 있습니다. 이러한 값이 변경되면 버그가 발생할 수 있습니다. 예를 들어, 상수 세트는 예를 들어 특정 비트 패턴을 형성하도록 선택 될 수 있습니다 public static final int R = 4, W = 2, X = 1
. 이러한 구조가 다른 구조를 형성하도록 변경되면 R = 0, W = 1, X = 2
기존 코드와 같은 코드 boolean canRead = perms & R
가 잘못됩니다. 그리고 그에 따른 재미가 Integer.MAX_VALUE
바뀌는 것이라고 생각 하십시오! 여기에는 수정이 없으며 일부 상수 의 값이 실제로 중요하며 단순히 변경할 수 없다는 것을 기억하는 것이 중요합니다.
그러나 대부분의 상수의 경우 위의 제한 사항을 고려하면 변경하는 것이 좋습니다. 상수는 특정 값이 중요하지 않은 의미로 변경하기에 안전합니다. 이 같은 튜너 블의 경우를 예입니다 BORDER_WIDTH = 2
거나 TIMEOUT = 60; // seconds
또는 템플릿과 같은 API_ENDPOINT = "https://api.example.com/v2/"
-하지만 틀림없이 그 일부 또는 모든 구성 파일이 아닌 코드에 지정되어야한다.