언젠가 CS 공부 기록이랑 면접 대비용 Java 이론을 정리할 생각이긴 했는데, 당장 시작할 생각은 없었다.
근데 오블완 챌린지가 열리는 바람에 일단 전에 쓰다 만 거부터 올려본다.
Brief Summary
static: 고정된
그렇다. static은 고정된 것을 말한다. 그게 무슨 뜻일까?
static 변수와 메서드는
- static 영역에 저장된다.
- 클래스 소속이다. (인스턴스 소속이 아니다)
- 동기화 문제에 주의해야 한다.
사실, 이 세 가지는 같은 말을 하고 있다.
static은 클래스 소속이기에 static 영역에 저장되고, 동시에 반대로 static 소속이기에 인스턴스(객체)에 관계 없이 클래스 소속으로 고정된다. 그렇기 때문에 마땅히, 각 인스턴스에서 호출해서 사용할 경우 동기화 문제에 주의해야 한다.
더 자세히 알아보자.
1. Static area (Method area)
자바 메모리 구조는 heap, stack, static(method) 영역으로 구분됨. 그 외에 PC Register 영역과 Variable Method 영역도 있긴 하지만 여기에선 별로 중요하지 않으므로 앞선 주요 영역 3개만 가지고 이야기 하자고.
heap 영역은 일반 영역임. 여기는 GC가 관리하는데, GC의 관리 방법에 대해서는 다음에 따로 포스팅 하겠음.
stack 영역은 호출된 것들의 영역임. 해당 호출이 끝나고 return 되면 해당 영역에 저장된 것들은 바람과 함께 사라짐.
자, 그럼 대망의 static.
static 영역은 클래스의 영역임. 여기는 임시적인 것들은 저장하지 않음. 오직 고정된, 혹은 고정해야하는 것 만을 저장한다. 여기 저장된 것들은 클래스가 로드될 때 함께 생성되어 프로그램 종료시까지 유지된다. 즉, 소속된 해당 클래스와 명운을 같이한다. 클래스의 생성자가 실행되든 말든, 그래서 인스턴스(객체)가 생기든 말든 관심 없다. 오직 클래스 그 자체에 귀속되어 있다.
static 영역은 GC의 손길에서 벗어나 있다. GC가 건드리지 않아서 static인지, static이라서 GC가 건드리지 않는지는 중요하지 않다. 여하튼 GC는 메모리가 부족해도 static은 거들떠 보지 않는다는 게 중요하다. 그 말은 곧, 오래도록 호출하지 않아도 static으로 선언한 변수와 메서드는 멀쩡할 것이라는 뜻이며, 동시에 개발자가 직접 신경쓰지 않으면 static 메모리는 관리가 안 될 것이라는 뜻이다. 생각없이 static을 계속 선언해도 아무도 날 말려주지 않을 것이고 그러다 정말 중요한 것을 저장할 수 없게 될 거라는 뜻이다!
2. 클래스 소속
왜 static을 static 영역에 저장할까? 이름이 같아서? 그건 인과가 반대된 거겠지? static 영역에 저장해서 static인지 static을 저장해서 static 영역인지는 내 알 바가 아니다. 중요한 것은 static은 고정된 값이라는 것이다. 이렇게 말하면 final이랑 헷갈릴 수 있는데, final은 '고정된 값'으로, 값이 하나의 형식와 내용으로 고정된, 즉 변경 불가능의 의미를 표현한다. 반면 static은 '고정된' 값으로, 이 static 멤버(변수 + 메서드)들은 클래스 자체에 고정되어 있다.
즉, 해당 클래스의 인스턴스가 몇 개가 생성되든 이 모든 인스턴스들이 같은 static 멤버를 공동으로 사용하게 된다. static 멤버는 클래스 로드시에 생성되니 사실상 인스턴스 그 자신들보다 먼저 생성된 셈이다. 감히 까마득한 선배(?)를 와라 가라 할 수는 없지 않겠는가. 이렇게 static은 인스턴스에 독립적인 클래스 그 자체의 상태값이나 특수한 행위를 표현하기 위해 사용한다.
static을 호출할 때는 그래서 인스턴스 생성이 불필요하다. 클래스 내부에서는 당연히 이름만 불러주면 되고, 클래스 외부에서 호출할 때도 그냥 클래스명 뒤에 도트 연산자를 붙이고 바로 호출해주면 된다.
때문에 static 메서드에서 다른 일반 메서드를 불러오기는 까다롭다. static은 클래스 소속이지만 다른 일반 메서드들은 해당 클래스로 만든 실 구현체, 즉 인스턴스(객체)가 있어야 비로소 존재하기 때문이다. 그래서 이를 위해 따로 인스턴스를 생성하고 나서야 일반 메서드를 호출할 수 있다. 개인적으로는 A 클래스 안에서 A 클래스의 인스턴스를 만들게 되는 꼴이라 별로 좋아하지 않지만, 정 필요하다면 해야지 어쩌겠나.
3. 동기화 문제 주의
앞에서 이미 언급했지만, static은 클래스 소속이라서 해당 클래스의 모든 인스턴스가 이를 공유한다. 그런데 이를 final로 선언하지 않으면 이 값은 변경가능하다. 이 말은 곧, 같은 클래스로 선언된 여러 인스턴스가 동시에 static 멤버를 사용할 수 있다는 뜻이다. 그 사용이 조회면 상관이 없지만 만약 변경이면? 그야말로 불타는 피자짤 탄생이다.
이 때문에 쓰레드에 신경써서 개발을 하거나, 아니면 아예 final로 고정시켜 버리는 것이 속 편하다. 고정시키면 어떻게 바꾸냐고? 안 바꾸면 된다. 어차피 객체에 구애받지 않는 값이란 건 클래스 초기 생성시 고정된 상태태값이거나, 생성자에서 받아서 사용할 초기값, 변경할 필요 없는 조회용 값이 대부분이다. 따지자면 static은 변경 및 수정할 필요 없는 값을 넣는 곳이고, 그렇게 사용하는 것이 현명하다.
정리
: static은 static 영역에 저장되는 클래스 자체의 값이므로, 변경 및 수정이 자주 필요한 값 보다는 다양한 인스턴스에서도 조회했을 때 같은 값이 나와야 하는 클래스 상태 조회용 값으로 사용하는 것이 일반적이다. 혹시 변경 및 수정해야 할 일이 생기면 동기화 문제에 주의하자.
'CS 이론 정리' 카테고리의 다른 글
객체 생성의 모든 것 (2) - 업캐스팅 (2) | 2024.11.09 |
---|---|
객체 생성의 모든 것 (1) - 문자열 (1) | 2024.11.08 |