Java static 완벽 해설: 변수, 메서드, 블록과 실전 예제
Java에서 static 키워드는 정적 변수, 정적 메서드, 정적 블록 세 가지 문맥에서 사용됩니다. 각각은 클래스와 인스턴스의 생명주기에서 고유한 역할을 합니다.
Java 정적 변수
정적 변수는 클래스가 처음 로드될 때 단 한 번 초기화되는 클래스 수준의 필드입니다. 인스턴스 변수와 달리, 정적 변수의 단일 복사본이 해당 클래스의 모든 객체에 의해 공유됩니다.
- 단 하나의 복사본만 존재하며 모든 인스턴스가 공유
- 객체 생성 없이
ClassName.variableName으로 직접 접근 가능
- 인스턴스 필드보다 먼저 초기화됨
문법:
public static int count;
Java 정적 메서드
정적 메서드는 특정 인스턴스가 아닌 클래스에 속합니다. 객체 생성 없이 호출할 수 있으며 정적 데이터만 접근할 수 있습니다.
- 다른 정적 메서드는 호출 가능하지만 인스턴스 메서드는 호출 불가
ClassName.methodName()으로 호출
- 인스턴스에 묶이지 않으므로
this나 super 사용 불가
모든 main 메서드는 정적이므로, 객체가 존재하기 전에 JVM이 애플리케이션을 실행할 수 있습니다.
실전 예제: 정적 변수와 메서드 사용
아래는 여러 Student 객체 간에 정적 카운터가 공유되는 것을 보여주는 간단한 프로그램입니다.
public class Demo {
public static void main(String[] args) {
Student s1 = new Student();
s1.showData();
Student s2 = new Student();
s2.showData();
// Student.b++; // 주석 해제하여 카운터 수정
// s1.showData();
}
}
class Student {
int a; // 인스턴스 변수, 기본값 0
static int b; // 정적 카운터, 한 번만 0으로 초기화
Student() {
b++; // Student 생성될 때마다 카운터 증가
}
public void showData() {
System.out.println("Value of a = " + a);
System.out.println("Value of b = " + b);
}
}
java Demo로 컴파일하고 실행하면 다음 출력을 볼 수 있습니다:
아래 다이어그램은 참조 변수와 객체가 생성되는 방식, 그리고 정적 변수 b가 인스턴스 간에 공유되는 방식을 보여줍니다.
클래스 외부에서 정적 변수에 접근하려면 ClassName.variableName을 사용하세요:
Student.b++; // 공유 카운터 증가
s1.showData(); // 업데이트된 b 값 표시
정적 컨텍스트에서 인스턴스 변수에 접근하려 하면 컴파일 에러가 발생합니다:
error: non-static variable a cannot be referenced from a static context
a++;
이는 정적 메서드가 인스턴스 필드와 직접 상호작용할 수 없기 때문입니다.
Java 정적 블록
정적 블록은 클래스가 JVM에 처음 로드될 때 한 번 실행되는 특수한 코드 블록입니다. 단순 대입 이상의 복잡한 초기화가 필요한 정적 필드를 초기화하기에 이상적입니다.
class Test {
static int a;
static int b;
static {
a = 10;
b = 20;
}
}
다음 프로그램은 정적 블록의 출력을 보여줍니다:
public class Demo {
static int a;
static int b;
static {
a = 10;
b = 20;
}
public static void main(String[] args) {
System.out.println("Value of a = " + a);
System.out.println("Value of b = " + b);
}
}
출력:
Value of a = 10
Value of b = 20