Static 보충자료
자바 메모리 구조
자바 프로그램 실행 시 JVM(Java Virtual Machine)은 메모리를 다음과 같이 나눕니다.
1. 메서드 영역 (Method Area)
정의: 프로그램 실행에 필요한 공통 데이터를 관리하는 영역입니다.
특징:
클래스에 대한 정보(
클래스 이름,메서드,필드 정보)가 저장됩니다.static 변수와 같은 클래스 수준의 데이터가 저장됩니다.
2. 스택 영역 (Stack Area)
정의: 실제 프로그램의 메서드가 실행될 때 사용되는 메모리 공간입니다.
특징:
스택 프레임(Stack Frame): 메서드 호출 시 생성되며, 지역 변수 및 호출 정보를 저장합니다.
메서드 실행이 종료되면 해당 스택 프레임은 제거됩니다.
LIFO(Last In, First Out) 구조로 작동합니다.
3. 힙 영역 (Heap Area)
정의: 객체 인스턴스와 배열이 생성되는 영역입니다.
특징:
런타임 중 동적 메모리 할당이 이루어집니다.
new키워드를 통해 생성된 객체는 힙 영역에 저장됩니다.힙 영역에 있는 객체는 스택에 저장된 참조 변수를 통해 접근합니다.
스택과 큐
스택 (Stack)
정의: 후입선출 (LIFO, Last In First Out) 방식의 자료 구조입니다.
특징:
마지막에 추가된 데이터가 가장 먼저 제거됩니다.
주로 함수 호출, 되돌리기 기능 등에 사용됩니다.
import java.util.Stack;
public class StackExample {
public static void main(String[] args) {
Stack<Integer> stack = new Stack<>();
stack.push(10); // 데이터 추가
stack.push(20);
System.out.println(stack.pop()); // 20 (후입선출)
System.out.println(stack.peek()); // 10 (마지막 데이터 확인)
}
}
큐 (Queue)
정의: 선입선출 (FIFO, First In First Out) 방식의 자료 구조입니다.
특징:
먼저 추가된 데이터가 먼저 제거됩니다.
주로 대기열 처리, BFS 등에서 사용됩니다.
import java.util.LinkedList;
import java.util.Queue;
public class QueueExample {
public static void main(String[] args) {
Queue<Integer> queue = new LinkedList<>();
queue.offer(10); // 데이터 추가
queue.offer(20);
System.out.println(queue.poll()); // 10 (선입선출)
System.out.println(queue.peek()); // 20 (첫 번째 데이터 확인)
}
}
Static (정적 변수)
Static 변수란?
클래스 로딩 시 메모리에 적재되며, 프로그램 종료 시까지 유지됩니다.
클래스 수준에서 공유되며, 모든 객체가 동일한 메모리 위치를 참조합니다.
**메서드 영역(Method Area)**에서 관리됩니다.
객체마다 다른 값을 가지는 인스턴스 변수와 달리 공유 데이터를 저장하는 용도로 사용됩니다.
사용 이유
객체 간 공유되는 데이터를 저장하거나 관리하기 위해 사용합니다.
자주 사용되는 상수, 설정값, 전역 변수 등에 적합합니다.
class StaticVariableExample {
static int sharedCounter = 0; // Static 변수 (공유 데이터)
int instanceCounter = 0; // 인스턴스 변수 (객체마다 별도)
void incrementCounters() {
sharedCounter++; // Static 변수는 모든 객체가 공유
instanceCounter++; // 인스턴스 변수는 객체마다 별도 관리
}
public static void main(String[] args) {
StaticVariableExample obj1 = new StaticVariableExample();
StaticVariableExample obj2 = new StaticVariableExample();
obj1.incrementCounters();
obj2.incrementCounters();
System.out.println("obj1.instanceCounter: " + obj1.instanceCounter); // 1
System.out.println("obj2.instanceCounter: " + obj2.instanceCounter); // 1
System.out.println("sharedCounter: " + StaticVariableExample.sharedCounter); // 2 (모든 객체가 공유)
}
}인스턴스 변수 vs 클래스 변수
구분
인스턴스 변수
클래스 변수 (Static)
소유주
각 객체가 개별적으로 소유
클래스에 속함
메모리 위치
힙(Heap) 영역
메서드(Method) 영역
접근 방식
객체를 통해 접근
클래스명 또는 객체를 통해 접근 가능
초기화 시점
객체 생성 시
클래스 로딩 시
인스턴스 변수와 클래스 변수의 접근 방법
인스턴스 변수
객체를 생성한 후에 접근 가능합니다.
인스턴스명.변수명으로 접근합니다.
클래스 변수 (Static 변수)
클래스명으로 직접 접근하는 것이 권장됩니다.
클래스명.변수명또는인스턴스명.변수명으로 접근 가능합니다.
class VariableExample {
int instanceVariable = 10; // 인스턴스 변수
static int classVariable = 20; // Static 변수
public static void main(String[] args) {
VariableExample obj1 = new VariableExample();
VariableExample obj2 = new VariableExample();
// 인스턴스 변수는 각 객체별로 독립적
obj1.instanceVariable = 30;
obj2.instanceVariable = 40;
// Static 변수는 모든 객체가 공유
VariableExample.classVariable = 50;
// 출력
System.out.println("obj1.instanceVariable: " + obj1.instanceVariable); // 30
System.out.println("obj2.instanceVariable: " + obj2.instanceVariable); // 40
System.out.println("classVariable (obj1): " + obj1.classVariable); // 50
System.out.println("classVariable (obj2): " + obj2.classVariable); // 50
}
}
Static(메서드)
Static 메서드란?
클래스 로딩 시 함께 적재되며, 객체를 생성하지 않아도 클래스명으로 호출 가능합니다.
Static 메서드는 **객체의 상태(인스턴스 변수, 메서드)**에 의존하지 않고, 클래스 수준에서 동작합니다.
Static 메서드의 제약
Static 메서드는 인스턴스 변수나 인스턴스 메서드에 직접 접근할 수 없습니다.
클래스 변수(Static 변수)나 다른 Static 메서드만 사용할 수 있습니다.
Static 메서드와 인스턴스 메서드의 차이
Static 메서드는 상태에 독립적인 작업(예: 유틸리티 메서드)에 적합합니다.
인스턴스 메서드는 객체의 상태를 조작하거나 반환하는 작업에 적합합니다.
Static 메서드의 사용
class StaticMethodExample {
static int sharedCounter = 0;
static void incrementCounter() { // Static 메서드
sharedCounter++;
System.out.println("Shared Counter: " + sharedCounter);
}
public static void main(String[] args) {
StaticMethodExample.incrementCounter(); // 클래스명으로 호출
StaticMethodExample.incrementCounter();
}
}
Static 메서드의 제약
class StaticRestrictionsExample {
int instanceCounter = 0; // 인스턴스 변수
static int sharedCounter = 0; // Static 변수
static void staticMethod() {
// instanceCounter++; // 컴파일 오류 (Static 메서드에서 인스턴스 변수 접근 불가)
sharedCounter++; // Static 변수 접근 가능
System.out.println("Static Counter: " + sharedCounter);
}
void instanceMethod() {
instanceCounter++; // 인스턴스 변수 접근 가능
sharedCounter++; // Static 변수도 접근 가능
System.out.println("Instance Counter: " + instanceCounter);
System.out.println("Static Counter: " + sharedCounter);
}
public static void main(String[] args) {
StaticRestrictionsExample obj = new StaticRestrictionsExample();
StaticRestrictionsExample.staticMethod(); // Static 메서드 호출
obj.instanceMethod(); // 인스턴스 메서드 호출
}
}
Static 변수
클래스 수준에서 공유되는 데이터로, 클래스명으로 접근하는 것이 권장됩니다.
메서드 영역에서 관리되며, 모든 객체가 동일한 값을 참조합니다.
인스턴스 변수
각 객체가 개별적으로 소유하며, 객체 생성 후에 접근 가능합니다.
Static 메서드
클래스명으로 호출 가능하며, 객체의 상태에 의존하지 않습니다.
인스턴스 변수와 메서드에 접근할 수 없으며, 클래스 수준의 데이터(Static 변수)에만 접근 가능합니다.
Last updated