클래스 변수(Class variable) vs 인스턴스 변수(Instance variable) vs 지역 변수(local variable)
2022. 12. 31. 00:05
1. 클래스 변수(Class variable) vs 인스턴스 변수(Instance variable)
멤버 변수 중 static이 붙은 것은 클래스 변수, 붙지 않은 것은인스턴스 변수이다.
클래스 변수(Static 멤버)
- 클래스 내에 Static 키워드로 선언된 변수
- 처음 JVM이 실행되어 클래스가 메모리에 올라갈 때 ~ 프로그램이 종료될 때까지 유지
- 클래스가 여러 번 생성되어도 Static 변수는 처음 딱 한 번만 생성됨
- 동일한 클래스의 모든 객체들에 의해서 공유됨
인스턴스 변수(Non-static 멤버)
- 클래스 내에 선언된 변수
- 객체 생성 시마다 매번 새로운 변수가 생성됨
- 클래스 변수와 달리 공유되지 않음
지역변수
- 메소드 블럭 안에 선언된 변수로 메소드 호출 시점 ~ 메소드 종료 시점 동안 유지된다.
변수의 종류 | 선언 위치 | 생성 시기 |
클래스 변수(class variable) | 클래스 영역 | 클래스가 메모리에 올라갈 때 |
인스턴스 변수(instance variable) | 인스턴스가 생성되었을 때 | |
지역 변수(local variable) | 클래스 영역 이외의 영역(메서드, 생성자, 초기화 블럭 내부) | 변수 선언문이 수행되었을 때 |
아래 예제에서 클래스 변수 classVar는 처음 한 번만 생성되고 동일한 객체를 staticTest1과 staticTest2에서 서로 공유하기 때문에 둘 다 바뀌지만, instanceVar는 객체 생성 시 마다 매번 새로 메모리에 할당되기 때문에 staticTest1.instanceVar만 변경된다.
public static class StaticTest {
static int classVar = 10; //클래스 변수
int instatnceVar = 28; //인스턴스 변수
public void method() {
int localVar = -100; //지역변수(메소드 블럭 내에서만 사용 가능)
System.out.println(localVar);
}
}
public static void main(String[] args){
StaticTest staticTest1 = new StaticTest();
StaticTest staticTest2 = new StaticTest();
System.out.println("1. " + staticTest1.classVar + ", " + staticTest1.instanceVar);
System.out.println("2. " + staticTest2.classVar + ", " + staticTest2.instanceVar);
staticTest1.classVar = 12;
staticTest1.instanceVar = 400;
System.out.println();
System.out.println("1. " + staticTest1.classVar + ", " + staticTest1.instanceVar);
System.out.println("2. " + staticTest2.classVar + ", " + staticTest2.instanceVar);
}
// 출력 결과
1. 10, 28
2. 10, 28
1. 12, 400
2. 12, 28
2. 클래스 변수, 인스턴스 변수, 지역 변수가 메모리에 적재되는 위치
메소드 영역
- 클래스에 대한 정보와 함께 클래스 변수(static variable)가 저장되는 영역.
- JVM은 자바 프로그램에서 특정 클래스가 사용되면 해당 클래스의 클래스 파일(*.class)을 읽어들여, 클래스에 대한 정보를 메소드 영역에 저장한다.
힙 영역
- 모든 인스턴스 변수(멤버 변수)가 저장되는 영역.
- new 키워드를 사용해 인스턴스가 생성되면, 해당 인스턴스의 정보를 힙 영역에 저장한다.
- 힙 영역은 메모리의 낮은 주소 -> 높은 주소의 방향으로 할당된다.
스택 영역
- 메소드가 호출될 때, 메소드의 스택 프레임이 저장되는 영역.
- 메소드 호출 시, 메소드 호출과 관계되는 매개변수와 지역 변수를 스택 영역에 저장한다.
- 스택 영역은 메소드의 호출과 함께 할당되며, 메소드의 호출이 완료되면 소멸한다.
- 스택 영역에 저장되는 메소드의 호출 정보를 스택 프레임이라고 부른다.
- 후입 선출의 구조를 갖고 있으며, 메모리의 높은 주소에서 낮은 주소의 방향으로 할당된다.
3. 클래스 변수(Static)의 주의점, 클래스 변수가 필요한 이유
주의- 실제 static 멤버의 생성 시점은 JVM에 따라 다르다.
- 보통 JVM은 필요한 대부분의 클래스를 처음부터 로딩하기 때문에 static멤버의 생성 시점은 JVM이 시작되는 시점이라고 할 수 있다.
- 제약조건
- static 메소드는 오직 static멤버만 접근 가능
- => static메소드도 static멤버와 로드되는 시점이 동일하기 때문에 객체가 생성되지 않은 상황에서도 변수를 사용할 수 있어야 한다.
- this 키워드 사용 불가
- => this는 호출 당시 실행 중인 객체를 가리키는 레퍼런스인데 static메소드는 객체가 생성되지 않은 상황에서도 호출이 가능하기 때문이다.
클래스 변수가 필요한 이유
- 자바에서는 캡슐화 원칙에 따라서 C/C++과 달리 어떤 변수나 함수도 클래스 바깥에 존재할 수 없다. 따라서 전역변수나 전역메소드로 사용해야 할 경우 static을 이용해서 해결한다.
참고
반응형
'Java' 카테고리의 다른 글
GC (Garbage Collection) 란? (1) | 2023.01.11 |
---|---|
해시맵(HashMap)이란? (0) | 2023.01.11 |
Java는 포인터(Pointer)가 없는데 왜 NullPointerException이 발생할까? (0) | 2022.12.27 |
0.1이 진짜 0.1이 아닌 이유(부동소수점(Floating Point)) (0) | 2022.12.13 |
JAVA 자료형 (0) | 2022.02.22 |