변수의 스코프와 static의 개념에 대해 알아보기 전에, 변수의 종류와 메모리 영역에 대하여 알아야 한다.

public class VariableScopeExam {
int globalScope = 10; // 인스턴스 변수
static int staticVal = 7; // 클래스 변수(= static 변수)
public void scopeTest(int value){ // 매개변수
int localScope = 20; // 지역변수
System.out.println(globalScope);
System.out.println(localScope);
System.out.println(value);
}
}
선언 위치에 따라 변수는 선언된 위치에 따라 클래스변수, 인스턴스변수, 지역변수로 나눌 수 있다.
메모리 공간(Runtime Data Area)은 크게 Method(Static) 영역, Stack 영역, Heap 영역으로 구분되고 데이터 타입(자료형)에 따라 각 영역에 나눠서 할당 되게 된다.
1) Method(Static) 영역
✏️ 여기서 static이 붙지 않은 일반 인스턴스 변수들은 static 영역에 들어가지 않으며, 전역변수와 정적 맴버 변수(static 으로 선언되는 것)들의 데이터를 저장한다고 기억하고 있으면 된다.
2) Stack 영역
3) Heap 영역
✏️ new를 통해 인스턴스 객체를 생성했을 때, heap 영역에는 생성된 객체가 올라가고, Stack 영역에는 해당 객체에 대한 주소 값(Reference)이 저장하는 것이다.
static은 '정적인' 이라는 뜻을 가지고 있으며, static이 앞에 붙는 변수나 메서드는 어떤 객체에 소속되는 것이 아닌, 클래스에 고정되어 있는 변수나 메서드이다.
따라서 객체 생성 없이 사용할 수 있으며, 위에서 설명하였듯이 메모리에 고정적으로 할당된다. 프로그램이 시작되면 메모리의 static 영역에 적재되고, 프로그램이 종료될 때 해제된다.
여기서 주의하여할 점은, static 메서드 내에서는 인스턴스 변수를 사용할 수 없다는 것이다. 이는 static한 메서드가 사용되는 시점에 해당 클래스가 인스턴스화되지 않았을 수도 있기 때문이다.
쉽게 말하면 static 메서드는 는 객체 생성 없이 사용할 수 있는데, 인스턴스 변수는 객체의 속성이므로 사용할 수 없는 것이다. 따라서 static 메서드 내에서 인스턴스 변수를 사용하면 컴파일 오류가 발생한다!
또 static한 필드는 인스턴스를 생성할 때 만들어지는 것이 아니라고 하였으므로, 값을 저장할 수 있는 공간도 하나밖에 없다. 즉 값을 공유하는 것이다. 그래서 같은 클래스에 대해 2개의 인스턴스를 생성하여 static 변수에 각각 다르게 값을 할당하여도 공유하기 때문에 최종적으로 할당한 값이 출력될 것이다.
변하지 않는 값이라면 final을 붙여 생성해야 한다.