여러 코테를 치면서 프로그래머스 외에 자체 사이트나 자바 웹 컴파일러 사이트를 경험했다. 그런데 종종 메서드에 static을 붙이지 않으면 에러가 발생하는 사이트들이 있었다. 그래서 습관적으로 static을 코테에서 사용하다가 너무 근거없는 사용을 하는 것처럼 느껴졌다. 그래서 static의 개념은 당연히 알고있지만 이에 대해 좀 더 파보고 싶어 오늘 제대로 정리해보려 한다.
참고 사이트 : coding-factory
영어로 고정된
이라는 뜻을 가진다.
자바에선 정적
으로 번역되어 클래스에 고정된다는 의미를 가진다.
자바에서 자원이 사용되려면 메모리를 할당 받아야 하는데
static 키워드를 통해 생성되면 Heap이 아닌 static 영역의 메모리에 할당된다. 이 영역은 동일한 클래스의 모든 객체가 공유한다.
Garbage Collector는 Heap 영역만 관리하기 때문에 static 영역에 있는 멤버는 프로그램 종료시 까지 메모리가 할당된 채로 존재한다.
static으로 선언되었다면 인스턴스를 생성하지 않고 클래스 레벨에서 바로 사용이 가능하다.
class Solution {
public long solution(int n, int m, int[][] tests) {
long answer = 0;
return answer;
}
}
public class Main {
public static void main(String[] args) {
}
}
static에 대해 알아보다 스택오버플로우에서 흥미로운 글을 봤다. static 변수가 왜 evil한지에 대한 내용이다.
물론 모든 상황에서 static이 나쁜건 아니다. 클래스 레벨에서 공유할 상왕이 있으면 사용을 하는 것이 맞다. 하지만 이 글에 static 변수의 무조건적인 사용을 지양해야되는 이유들이 잘 나와있어서 이를 정리해보려 한다.
Global State(전역 상태)의 문제
static 변수는 클래스 레벨에서 공유되기 때문에 여러 객체간 데이터를 공유할 수 있다. 이는 장점이 될 수있지만, 반대로 변수의 상태를 예측하기 어렵게 한다는 단점도 있다. 특히 다중스레드 환경에서 static 변수의 공유는 동기화 문제를 만들 수 있다.
테스트의 어려움
static 변수 때문에 단위테스트에 어려움을 겪을 수 있다. static 변수에 의존하는 코드는 의존성 주입과 같은 테스트 패턴을 적용하기 어려울 수 있다.
유지관리 문제
static 변수는 클래스 전체에서 접근 가능하므로 어디서든 수정할 수 있다. 그래서 유지관리 및 디버깅에 어려움을 겪을 수 있다. 특히 프로젝트가 커지면 다른 개발자들이 어떤 변수를 사용하고 수정하는지 파악하기 힘들어질 수 있다.
의존성 증가
static 변수의 사용은 클래스간의 강한 결합을 유발한다. 코드의 재사용성과 유연성이 떨어질 수 있다.
메모리의 낭비
static으로 올라간 변수는 garbage collector에 의해 정리되지 않는다. 사용을 하지 않아도 프로그램이 계속 켜져있는한 메모리에 상주하기 때문에 남발 시 메모리의 낭비를 불러온다.