본문 바로가기
자바 JAVA

java static 이란 무엇인가?

by 비타민찌 2026. 1. 8.
728x90

Static은 클래스 레벨의 멤버를 정의하는 키워드입니다.
static으로 선언된 변수/메서드는 객체 생성 없이 클래스명.멤버명으로 접근할 수 있고,

해당 클래스의 모든 인스턴스가 공유합니다.

 

메모리 관점에서 보면,

클래스가 로딩되면 클래스 메타데이터가 Method Area(HotSpot 기준 Metaspace) 에 적재되고,

static 멤버는 JVM이 클래스 단위로 관리합니다.


static 멤버의 수명은 보통 프로그램 종료까지로 이해해도 되지만,

정확히는 해당 클래스를 로딩한 ClassLoader의 수명에 종속됩니다.

(WAS/DevTools 환경에서는 ClassLoader 교체로 함께 정리될 수 있음)

 

1. Static의 특징

Static의 주요 특징은 다음과 같습니다.

public class Company {
    static String companyName = "Tech Corp";  // 모든 인스턴스가 공유
    String employeeName;                      // 인스턴스별로 다름

    static void printCompany() {
        System.out.println(companyName);      // OK
        // System.out.println(employeeName);  // 컴파일 에러 (인스턴스 멤버 접근 불가)
    }
}

// 사용
Company.companyName;      // 객체 생성 없이 접근
Company.printCompany();   // 객체 생성 없이 호출

Company emp1 = new Company();
Company emp2 = new Company();
// emp1과 emp2는 같은 companyName을 공유

 

  • 클래스 레벨 소속: static 멤버는 객체가 아니라 클래스에 속합니다.
  • 공유: 모든 인스턴스가 같은 static 값을 공유합니다.
  • 객체 생성 불필요: 클래스명.멤버명으로 바로 접근 가능합니다.
  • 제약사항: static 메서드는 인스턴스 멤버를 직접 사용할 수 없습니다. (this가 없음)

 

2. 메모리 관점에서의 Static

메모리 구조는 보통 이렇게 설명합니다.

 

[Method Area (HotSpot: Metaspace)]
- 클래스 메타데이터(클래스 구조, 메서드/필드 정보 등)
- 메서드 바이트코드/런타임 상수풀 등
→ JVM이 클래스 단위로 관리

[Heap]
- new로 생성된 객체(인스턴스)
- (구현체에 따라) 클래스 런타임 데이터/정적 필드 값이 힙에 존재하기도 함
→ GC 관리 대상

[Stack]
- 지역 변수, 매개변수, 호출 프레임
→ 스레드별 독립

 

여기서 static 멤버는

클래스 로딩 시 JVM이 클래스 단위로 준비하고 관리하며,

인스턴스 멤버는 new로 생성된 객체가 Heap에 만들어질 때 함께 생성됩니다.

 

3. Static, 실무 활용 사례

유틸리티 클래스, 상수 정의 시에 사용합니다.

 

 

4. Static의 장단점

장점

  • 공통 데이터 공유: 클래스 전체에서 같은 값/자원을 공유 가능
  • 편리한 접근: 객체 생성 없이 바로 사용 가능
  • 유틸/상수 표현에 적합: 의미적으로 클래스 소속임을 명확히 함

단점

  • 멀티스레드 이슈: 공유 상태(static mutable)는 동기화 필요
  • 테스트 어려움: 상태가 남아 테스트 독립성을 해칠 수 있음
  • 결합도 증가: 남용하면 전역 상태처럼 되어 설계가 나빠질 수 있음
  • 메모리/수명: ClassLoader 수명까지 유지될 수 있어(특히 WAS) 잘못 참조하면 누수 원인이 될 수 있음

 

 

5. 자주 하는 질문

Q1: Static 변수는 언제 초기화되나요?

A: 클래스가 처음 능동적으로 사용될 때 JVM이 클래스 초기화(initialization) 를 수행하며,

이때 static 필드 초기화와 static 블록이 딱 한 번 실행됩니다.

public class InitOrder {
    static int a = 10;
    static int b;

    static {
        b = 20;
        System.out.println("클래스 초기화");
    }
}

 

 

 

Q2: Static import는 무엇인가요?

A: static 멤버를 클래스명 없이 사용할 수 있게 하는 문법입니다.

 

 

Q3: Static 변수의 동기화는 어떻게 하나요?

A: synchronized 또는 Atomic 같은 동시성 도구를 사용합니다.

import java.util.concurrent.atomic.AtomicInteger;

public class SafeCounter {
    private static int count = 0;
    private static final AtomicInteger atomicCount = new AtomicInteger(0);

    public static synchronized void increment() {
        count++;
    }

    public static void increment2() {
        synchronized (SafeCounter.class) {
            count++;
        }
    }

    public static void increment3() {
        atomicCount.incrementAndGet();
    }
}

 

 

728x90

댓글