회사 코드를 봤을 때 'static final' 형태로 한쌍으로 자주 사용되고 있는 경우가 많았다.
특히 상수들을 정의해둔 클래스에서 많이 보였다.
있는 그대로 보자면 인스턴스 생성 전에 immutable 상수를 할당하여 다른 객체가 만들어질 때 사용되었다.
이 참에 전체적으로 정리를 하고자 한다.
static(정적)이란
- static이란 고정된 의미로 static이 붙은 클래스 멤버는 해당 class에 고정됨을 의미
- class에 고정된다는 것은 프로그램이 실행되고 메모리에 적재될 때 class와 같이 메모리에 적재된다.
- 따라서 class로 인스턴스를 생성하기 전부터 static 멤버는 사용가능하다.
- static 멤버가 할당되는 메모리는 static area 다.
- 모든 객체가 공유할 수 있다.
- 로딩되면서부터 생성되며 프로그램 종료 시 JVM에 반환한다.
- static area에는 정적, 클래스, 메타 데이터 등 을 저장한다.
- 프로그램 시작부터 종료까지 데이터는 유지된다.
- 자바 GC(garbage collector) 관리 대상이 아니다.
- static area = class area = method area 모두 동일
final이란
- 이름 그대로 최종을 의미
- final이 붙은 변수는 한 번 값이 할당되면 변경불가
- 프로그램 수행 중 수정 불가
- final 필드 초기화 방법
- 선언 시 초기화
- 생성자를 통한 초기화
- final 메서드
- final 메서드를 포함하는 클래스의 자식 클래스는 final 메서드 오버라이딩 불가
- final 클래스
- final클래스는 최종, 마지막 클래스로 상속불가
왜 static final 을 사용되는 모습이 자주 보일까
- 간단히 static final은 프로그램이 실행되는 동안 어디서든 접근가능하고 수정을 못하게 막는다.
- 특징
- 프로그램이 실행되는 동안 어디서든 바뀌지 않는다는 것을 의도
- 어디서든 접근이 가능하기 때문에 특정 클래스에 상수들을 모아 한 번에 관리가능
- 사용할 때마다 인스턴스를 굳이 만들지 않고 사용 가능
- 장점이 많아보이지만 모두 static final로 선언하면 GC의 관리 대상이 아니며 런타임 시 기본적으로 사용하는 메모리가 증가하게 된다.
그렇다면 final 만 사용하는 경우는 언제일까
대표적으로 Spring에서 DI에서 사용한다.
하지만 만약 static이 붙게되면 spring이 싱글톤으로 관리하는데 개발자가 실수로 같이 관리하게 되어 로직 수행 중 중간에 값이 바뀌는 경우가 발생할 수 있을 것 같다.
하지만 해당 경우는 발생하지 않을 것이다.
- 필드 주입을 한다면 final 키워드로 초기화 값을 넣어야 한다. 그렇게되면 더 이상 Spring 빈이 아니게 된다.
- 생성자 주입을 한다면 static 키워드로 생성자 메서드에 변수로 들어갈 수 없다.
public class MovieRecommender {
private final CustomerPreferenceDao customerPreferenceDao;
@Autowired
public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
this.customerPreferenceDao = customerPreferenceDao;
}
// ...
}
참고
https://coding-factory.tistory.com/524
https://coding-factory.tistory.com/525
'Java' 카테고리의 다른 글
Annotation 정리 (0) | 2023.07.17 |
---|---|
java int를 char로 형변환하기 (0) | 2023.02.11 |
PATH, CLASSPATH, BUILDPATH에 대해 (0) | 2021.12.29 |
[Java] 예외 처리 - custom exception (0) | 2021.09.22 |
[Java] 예외처리 시 주의 팁 (0) | 2021.09.19 |