
static은 객체가 아닌 클래스 자체에 소속되는 멤버를 만들 때 사용하는 키워드이다.
일반 필드(인스턴스 변수)는 객체를 생성할 때마다 각각 따로 만들어지지만, static 변수는 클래스당 단 하나만 생성되어 모든 객체가 공유한다.
static 변수는 다음과 같은 특징을 가진다.
아래 예제는 static 변수가 객체별로 존재하지 않고, 모든 객체가 같은 변수를 공유한다는 것을 보여준다.
public class StaticTest {
public static String name;
}
public class StaticMain {
public static void main(String[] args) {
StaticTest staticTest = new StaticTest();
staticTest.name = "gildong";
System.out.println(staticTest.name);
staticTest.name = "gilseo";
System.out.println(staticTest.name);
StaticTest staticTest2 = new StaticTest();
staticTest2.name = "gilnam";
System.out.println(staticTest2.name);
System.out.println(staticTest.name);
StaticTest.name = "gilbok";
System.out.println(staticTest.name);
}
즉, 객체를 여러 개 만들어도 static 변수는 하나라는 점이 핵심이다.
static 변수는 다음과 같은 상황에서 자주 사용된다.
아래 예제는 학생 객체를 생성할 때마다 학번이 자동으로 증가하도록 static 변수를 활용한 구조이다.
import lombok.Data;
@Data
public class Student {
public static int autoCode = 20260000;
private int studentCode;
private String name;
public Student(String name) {
studentCode = ++autoCode;
this.name = name;
}
}
public class StudentMain {
public static void main(String[] args) {
Student[] students = new Student[5];
students[0] = new Student("홍길동");
students[1] = new Student("홍길서");
students[2] = new Student("홍길남");
students[3] = new Student("홍길북");
students[4] = new Student("홍길중");
for (int i = 0; i < students.length; i++) {
System.out.println("학번: " + students[i].getStudentCode());
System.out.println("이름: " + students[i].getName() + "\n");
}
}
}
이 구조 덕분에 학번을 따로 관리하지 않아도 객체 생성 순서 자체가 학번이 되는 효과를 얻을 수 있다.
즉, 공통 상태는 static, 객체 고유 상태는 인스턴스 변수로 구분하는 것이 핵심이다.
static은 단순히 “객체 없이 쓰는 변수”가 아니라, 모든 객체가 공유하는 단 하나의 상태라는 점이 핵심이라는 걸 느꼈다.
특히 자동 증가 학번 예제처럼, 객체가 늘어날수록 static 변수의 역할이 분명해진다는 점이 인상적이었다.
앞으로 static 메서드, static 블록, 그리고 상수(static final)로 확장될 때도 이번에 정리한 “공유 개념”을 기준으로 이해하면 헷갈리지 않을 것 같다.