자바 static
IT 위키
더 많은 작업
자바의 static 은 필드나 메소드를 개별 객체가 아니라 클래스 자체에 소속시키는 키워드다. static 이 붙은 멤버는 객체를 생성하지 않고 클래스 이름만으로 사용할 수 있다.
자바에서 일반적인 필드와 메소드는 객체(인스턴스)마다 따로 존재하므로 `new` 로 객체를 만든 뒤에야 쓸 수 있다. 반면 static 멤버는 클래스가 메모리에 올라갈 때 한 번만 만들어지고 모든 객체가 그 하나를 공유한다. 따라서 객체 생성 없이 `클래스명.멤버명` 형태로 접근한다.
static 이 붙은 메소드를 정적 메소드 또는 클래스 메소드라고 한다.
public class Test {
public static void main(String[] args) {
System.out.print(Test.check(1));
}
static String check(int num) {
return (num >= 0) ? "positive" : "negative";
}
}
위에서 `check` 는 static 이므로 `Test` 객체를 만들지 않고 `Test.check(1)` 로 바로 호출한다. `main` 메소드가 static 인 것도 같은 이유다. 프로그램 시작 시점에는 아직 아무 객체도 없으므로 JVM 이 객체 없이 호출할 수 있어야 한다.
- 정적 메소드 안에서는 인스턴스 필드와 인스턴스 메소드를 직접 쓸 수 없다. 어느 객체의 것인지 정해지지 않았기 때문이다.
- 같은 이유로 `this` 와 `super` 를 쓸 수 없다.
- 인스턴스 메소드에서 정적 멤버를 쓰는 것은 반대로 아무 문제가 없다.
- 정적 메소드는 오버라이딩 되지 않는다. 하위 클래스에 같은 이름을 선언하면 재정의가 아니라 가리기(hiding)가 되며, 호출될 메소드는 실행 시점의 객체 타입이 아니라 컴파일 시점의 참조 타입으로 결정된다.
public class Counter {
static int count = 0;
Counter() { count++; }
}
`count` 는 모든 `Counter` 객체가 공유하므로 생성된 객체의 총 개수를 셀 수 있다. 공유 상태이므로 여러 스레드가 동시에 건드리면 동기화가 필요하다.
static {
// 클래스가 처음 로딩될 때 한 번만 실행된다
}
정적 필드를 복잡한 절차로 초기화해야 할 때 쓴다. 클래스 로딩 시 한 번만 실행된다.
| 구분 | static 멤버 | 인스턴스 멤버 |
|---|---|---|
| 소속 | 클래스 | 객체 |
| 생성 시점 | 클래스 로딩 시 | 객체 생성 시 |
| 개수 | 하나 | 객체마다 하나씩 |
| 접근 방법 | 클래스명.멤버명 | 참조변수.멤버명 |
| this 사용 | 불가 | 가능 |