-
[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을 선언한 변수를 사용하면 재할당하지 못하며, 해당 필드, 메서드별로 호출할 때마다 새로이 값이 할당(인스턴스화)한다.
그렇다면 상수로 사용하려고 할 때, 그 값은 변하지 않을 것인데 호출할 때마다 새롭게 인스턴스화할 필요가 없다. 한 번 메모리에 올려놓고 계속 같은 값을 갔다쓰면 될 일이다.
참조
[Java] static
static static이라는 의미는 ‘정적인, 움직이지 않는다.’는 뜻이다. 메모리에서 고정되기 때문에 붙은 이름이지만, 실제 소스에서 static을 사용한다는 의미는 모든 객체가 ‘공유’한다는 의미이다. cf.) 객체..
devbox.tistory.com
private final static attribute vs private final attribute
private final static attribute vs private final attribute
In Java, what's the difference between: private final static int NUMBER = 10; and private final int NUMBER = 10; Both are private and final, the difference is the static attribute. What's bett...
stackoverflow.com
'프로그래밍 언어 > 자바 & 코틀린' 카테고리의 다른 글
[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