-
[Java] 왜 private 상수는 관습적으로 private static final로 선언할까?프로그래밍 언어/자바 & 코틀린 2019. 7. 30. 13:09
private static final과 private final의 차이
public으로 사용하는 상수 타입은 enum을 이용하고 있다.
클래스 내부에서만 간단하게 사용할 상수를 만들 때, 아무 생각 없이 private static final을 사용하고 있는 나 자신을 보며 미리 초기화 값을 넣고 상수로 쓸거면 private final만 써도 되지 않나? 라는 의문을 갖기 시작했다.
예를 들면 아래의 예시처럼 일반적으로 사용하고 있었다.
public class ChocolateController { // logger를 선언할 때 private static final Logger logger = LoggerFactory.getLogger(ChocolateController.class); // 연차의 코드 값을 표현할 때 private static final String ANNUAL_LEAVE = "001"; // declare some methods }
그러기 전에 static, final에 대해 간단하게만 짚고 넘어가는 편이 좋을 것 같다.
static이란?
static은 '정적인', '움직임이 없는'으로 해석할 수 있는데, 이 static을 사용하면 메모리가 jvm의 static 메모리(해당 영역은 프로그램이 시작하고 종료될 때까지 살아있는다.) 에 올라간다. static 메모리에 올라가기 때문에 초기화 과정이 필요없어 static이 선언된 변수, 메서드에 곧장 접근이 가능하다.
public class Ketchup { // 변수에 static 사용 private static final String HEINZE = "heinze"; private static final String OTTOGI = "ottogi"; // 메서드에 static 사용 public static boolean isHeinzeKetchup(String brandName) { return brandName.equals(HEINZE); } public static boolean isOttogiKetchup(String brandName) { return brandName.equals(OTTOGI); } }
static을 사용한다는 의미는 해당 객체를 공유하겠다 는 의미이다.
여기저기서 해당 객체를 사용한다치면, 그 객체는 항상 동일한 객체라는 뜻이다.
(주의: 그래서 static이 선언된 변수의 값을 바꿔버리면 다른 곳에서 해당 변수의 값을 참조하는 부분의 값이 변한다.)
final이란?
final은 불변하도록 만드는 것이 아니라 재할당할 수 없도록 만드는 것이다. 상속을 하거나, 최초 초기화 이후 다시 초기화를 할 수 없다.
public class MutableTest { private final Map<String, Object> mutableMap = new HashMap<>(); public void testFinal() { // 재할당 안됨 // mutableMap = new HashMap<>(); mutableMap.put("choco", "M&M"); mutableMap.put("jelly", "haribo"); System.out.println(mutableMap.toString()); } public static void main(String[] args) { MutableTest mutableTest = new MutableTest(); mutableTest.testFinal(); } }
예시처럼, 재할당은 안되지만 값은 변할 수 있다.
하지만 대게 Collections타입(Map,List,Set)에 해당하고, 기본 데이터 타입인 int, boolean, char 등등에서는 재할당이 안되니 값을 변경할 수 있는 방법이 없다. 위의 예제에서 쓴 logger의 경우도 값이 변할 일이 없어보인다.
정리: 그럼 상수로 사용할 때, private static final인가?
private static final을 선언한 변수를 사용하면 재할당하지 못하며, 메모리에 한 번 올라가면 같은 값을 클래스 내부의 전체 필드, 메서드에서 공유한다.
private final을 선언한 변수를 사용하면 재할당하지 못하며, 해당 필드, 메서드별로 호출할 때마다 새로이 값이 할당(인스턴스화)한다.
그렇다면 상수로 사용하려고 할 때, 그 값은 변하지 않을 것인데 호출할 때마다 새롭게 인스턴스화할 필요가 없다. 한 번 메모리에 올려놓고 계속 같은 값을 갔다쓰면 될 일이다.
참조
private final static attribute vs private final attribute
'프로그래밍 언어 > 자바 & 코틀린' 카테고리의 다른 글
[Java] array(배열)과 arrayList(리스트)의 차이(arrayList는 어떻게 동적으로 늘어나는가?) (0) 2019.11.27 [Java] java8에서 생긴 람다(Lambda)를 쓰는 이유는 뭘까?(짧음 주의) (0) 2019.09.07 [Java] 터미널(terminal)로 war 파일 만들고 푸는 법 (0) 2019.03.17 [Java] java 파일을 class 파일로 컴파일 하는 방법(한글 인코딩 포함) (0) 2019.01.30 [java] 두 날짜간 월 차이 구하기 (0) 2018.12.10