✅ Static이란
Static은 '고정된'이란 뜻이며 정적이라고도 부른다. 클래스, 변수, 메서드에 static을 붙이면 말 뜻대로 고정된 클래스, 변수, 메서드가 된다. ( static 멤버 = 정적 멤버 )
정적 클래스는 생성자를 포함할 수 없고, 모든 멤버는 static으로 선언해야 한다.
정적 변수와 정적 메소드는 어떤 객체에 소속되지 않고, 클래스에 고정되어 있다. 객체에 소속되지 않으므로 객체 생성 없이 사용할 수 있다.
또한, 정적 메서드 내에서는 인스턴스 변수를 사용할 수 없다.
Static이 붙은 변수나 메서드는 객체를 생성하지 않고도 사용할 수 있다
✅ 예제 코드
public class StaticExample {
// 정적 변수 (모든 인스턴스가 공유)
static int staticVariable = 0;
// 정적 메서드 (클래스를 통해 직접 호출 가능)
static void staticMethod() {
System.out.println("This is a static method.");
System.out.println("Static variable in staticMethod: " + staticVariable);
}
// 인스턴스 변수 (각 객체가 개별적으로 가짐)
int instanceVariable;
// 생성자
public StaticExample(int instanceVariable) {
this.instanceVariable = instanceVariable;
staticVariable++; // 인스턴스 생성될 때마다 정적 변수 증가
}
// 인스턴스 메서드 (객체가 있어야 호출 가능)
public void display() {
System.out.println("Instance variable: " + instanceVariable);
staticMethod(); // 정적 메서드는 인스턴스 메서드 안에서 사용 가능
}
public static void main(String[] args) {
StaticExample.staticMethod(); // 클래스명으로 정적 메서드 호출
StaticExample instance1 = new StaticExample(1);
StaticExample instance2 = new StaticExample(2);
instance1.display(); // 객체마다 다른 instanceVariable 출력
instance2.display();
// 정적 변수는 모든 인스턴스가 공유
System.out.println("Static variable after instances created: " + StaticExample.staticVariable);
}
}
✅ 코드 결과
This is a static method.
Static variable in staticMethod: 0
Instance variable: 1
This is a static method.
Static variable in staticMethod: 2
Instance variable: 2
This is a static method.
Static variable in staticMethod: 2
Static variable after instances created: 2
🔍 설명:
- staticVariable: 클래스에 속한 변수이기 때문에 instance1, instance2가 공유합니다.
- 생성자 호출될 때마다 staticVariable++ → 2까지 증가
- staticMethod(): 클래스 이름으로 직접 호출 가능
- display()는 인스턴스 메서드이므로 instance1.display()처럼 객체가 있어야 호출 가능
- staticMethod()는 인스턴스 없이도 실행되므로 내부에서 instanceVariable은 접근 불가
✅ Static 멤버의 메모리 저장위치
일반적으로 우리가 new 연산을 통해 생성한 객체는 Heap 영역에 생성된다. 그리고 전역변수와 Static이 붙은 멤버들이 올라갈 수 있는 Static 메모리 공간이 따로 있다.
컴파일러는 Static이 붙은 변수, 메서드, 클래스들을 프로그램 실행과 동시에 Static 메모리 공간에 다 적재시킨다.
new 연산을 통해 객체를 생성하지 않아도 이미 컴파일러가 메모리 공간에 적재를 시킨 것이다.
그렇기 때문에, 우리가 new를 하지 않아도 Static 멤버에 접근할 수 있는 것이다.
Heap 메모리 공간은 GC를 통해 수시로 관리 되지만, Static 메모리 공간은 GC의 관리 영역 밖에 존재하므로 프로그램이 종료될 때까지 지워지지 않는다.
전역 변수 = Static 변수 ?
전역 변수는 일반적으로 프로그램 전체에서 사용되는 변수를 의미하지만, static 변수는 클래스 수준에서 사용되며 클래스 내에서 전역적으로 공유된다. 따라서 static 변수는 클래스 변수라고도 불리며, 전역 변수와는 약간 다른 개념이다.
✅ Static 사용을 지양해야 될 때
하지만, 프로그램이 종료될 때까지 메모리가 할당된 채로 존재한다는 것은 프로그램 성능에 영향을 줄 수 있다. 또한, 객체의 특정 상태를 사용해야 할 때는 Static을 사용할 수 없어서 객체지향적이지 않다고 말한다.
public class UserIdManager {
private static int userId;
public UserIdManager() { //생성자
userId = 0;
}
public static int generateUserId() {
return userId++;
}
}
위의 코드는 Static을 부적절하게 사용한 코드의 예시다.
이 클래스는 사용자 별로 할당되는 아이디를 관리하는 역할을 하려 하는데, userId가 static으로 선언되었기 때문에, 이 변수는 클래스 수준에서 공유된다. 이로 인해 여러 UserIdManager 인스턴스를 생성해도 userId는 하나만 존재하게 된다.
생성자에서 userId를 초기화하고 있지만, 이 생성자는 호출되지 않는다. 왜냐하면 generateUserId 메서드가 호출될 때마다 userId가 초기화되기 때문이다. 따라서 인스턴스 변수로 사용자 ID를 관리하는 것이 더 적절하다.
✅ Static 사용해야 될 때
Static을 사용해야 할 때는 여러 객체 간에 데이터를 공유하고자 할 때이다. 이때, Static을 사용하면 해당 클래스의 모든 인스턴스에서 동일한 값을 공유할 수 있다. 또한, 매번 인스턴스를 생성하지 않아 속도가 빠르고, 낭비되는 메모리를 줄일 수 있다.
따라서, Static을 남용하지 않아야 하고, 사용 의도를 정확히 알고 사용한다면 가독성이 좋고 효율적인 코딩을 할 수 있다 !
✏️ 공부한점
결국 Static을 쓰는 이유는 다음과 같다
- 공용 데이터 저장 (모든 객체가 공유해야 하는 값)
- 객체 없이 접근해야 할 기능 (예: 유틸 메서드 Math.random())
- 메모리 절약 (객체마다 따로 생성하지 않음)
'Back-end > Java' 카테고리의 다른 글
| [Java] CompletableFuture로 비동기 적용하기 (0) | 2025.08.20 |
|---|---|
| [JAVA] 컴파일 과정 (3) | 2025.08.11 |
| [JAVA] 추상클래스, 인터페이스 특징 및 차이점 (3) | 2025.08.08 |
| [Java] final 키워드 심화 정리 (3) | 2025.08.05 |
| [Java] 가비지 컬렉터(GC) 이해하기 (5) | 2025.08.04 |