1 분 소요

자바 필드 구분(클래스 변수, 인스턴스 변수, 지역 변수)은 메모리 구조와 수명 주기를 이해하는 첫걸음입니다. 올바르게 구분·사용하면 메모리 효율을 높이고 버그를 예방할 수 있습니다.


클래스 변수 static – 모든 인스턴스가 공유하는 데이터

특징

  • static 키워드로 선언 → 클래스 로드 시 메서드 영역에 1회 생성
  • 인스턴스를 만들지 않고 클래스명.필드 로 접근
  • 프로그램 종료까지 유지되어 전역 상태 관리에 유용
class Config {
    static int MAX_USER = 100;   // 클래스 변수
}
System.out.println(Config.MAX_USER);

사용 팁

  • 상수public static final 로 선언하고 대문자 스네이크(MAX_USER) 사용
  • 다중 스레드 환경에서는 동기화(e.g., AtomicInteger) 고려

인스턴스 변수 – 객체마다 고유한 상태

특징

  • static 키워드 없음
  • 힙(Heap) 영역에 저장되고 가비지 컬렉터가 관리
  • 각 객체가 독립 값 보유 → 한 인스턴스 변경이 다른 인스턴스에 영향 없음
class User {
    String name;          // 인스턴스 변수
}
User u1 = new User();
User u2 = new User();
u1.name = "Alice";
u2.name = "Bob";  // u1.name은 그대로 "Alice"

사용 팁

  • 필드는 기본적으로 *private** 으로 숨기고 Getter/Setter로 캡슐화
  • 불변 객체(Immutable)가 필요하면 final + Setter 제거

지역 변수 – 메서드·블록 내부의 일시적 값

특징

  • 스택(Stack) 에 저장 → 블록 종료 시 즉시 소멸
  • 명시적 초기화 필수 (컴파일러가 기본값 부여 X)
  • public/private/static과 같은 접근 제어 불가 (메서드 로컬 영역)
void doWork() {
    int counter = 0;      // 지역 변수
    System.out.println(counter);
}

사용 팁

  • 블록 범위를 최소화해 메모리 사용과 사이드이펙트 감소
  • 람다/익명 클래스에서 사용 시 effectively final 요건을 충족해야 함

필드 구분 비교표

구분 키워드 메모리 위치 생성 시점 소멸 시점 기본 초기화
클래스 변수 static 메서드 영역 클래스 로드 JVM 종료 자동
인스턴스 변수 (없음) 객체 생성 객체 소멸 자동
지역 변수 (없음) 스택 블록 진입 블록 종료 필수 수동 초기화

필드 활용 베스트 프랙티스

  • 상수 → public static final
  • 공통 설정 → private static + Getter
  • 객체 상태 → private 인스턴스 변수
  • 계산용 임시 값·루프 인덱스 → 지역 변수

질문 정리

Q1. 클래스 변수는 왜 가끔 final과 함께 쓰나요?

→ 값이 변하지 않는 전역 상수로 보장하기 위해 static final 조합을 사용합니다.

Q2. 지역 변수를 초기화하지 않으면 어떤 오류가 나나요?

→ 컴파일 단계에서 “variable might not have been initialized” 에러가 발생합니다.

Q3. 인스턴스 변수는 스레드마다 별도 메모리를 가지나요?

→ 아닙니다. 인스턴스가 동일하면 스레드와 무관하게 값을 공유합니다. 필요하다면 ThreadLocal을 사용하세요.

Q4. 왜 static 필드에 this를 사용할 수 없나요?

static은 클래스 레벨이라 인스턴스 참조(this)가 존재하지 않기 때문입니다.

Q5. 가비지 컬렉션이 클래스 변수를 회수할 때도 있나요?

→ 클래스 언로딩 시점에 함께 회수될 수 있지만, 일반적으로 JVM 종료까지 유지된다고 보는 것이 안전합니다.

카테고리:

업데이트:

댓글남기기