객체지향 프로그래밍(OOP)을 처음 배울 때, static 변수와 instance 변수의 개념은 헷갈리기 마련입니다. 이 두 가지는 매우 중요한 개념이지만, 각각의 용도와 차이를 정확히 이해하지 못하면 코드 작성 시 예상치 못한 문제가 생길 수 있습니다. 이 글에서는 static 변수와 instance 변수의 차이점, 그리고 언제 어떤 변수를 사용해야 하는지 명확하게 설명하겠습니다.
1. Static 변수란?
Static 변수는 클래스 자체에 속하며, 모든 인스턴스가 공유하는 변수입니다. 즉, 클래스가 로드될 때 메모리에 한 번만 할당되고, 이 변수는 해당 클래스를 사용하는 모든 객체가 동일한 값을 공유하게 됩니다.
Static 변수의 특징:
- 클래스 레벨에서 선언되며 객체 생성과 상관없이 존재
- 클래스가 로드될 때 메모리에 할당되고, 프로그램이 종료될 때까지 유지
- 모든 객체가 공유하는 값
Static 변수 예시:
class Car {
static int totalCars = 0; // 모든 Car 객체가 공유하는 변수
String model;
Car(String model) {
this.model = model;
totalCars++; // Car 객체가 생성될 때마다 totalCars 증가
}
}
위 예시에서 totalCars
는 static 변수로 선언되어 모든 Car
객체가 공유합니다. 즉, Car
객체가 생성될 때마다 totalCars
의 값은 모든 객체에 걸쳐 증가하게 됩니다.
2. Instance 변수란?
Instance 변수는 클래스의 각 객체(인스턴스)에 속한 변수입니다. 이 변수는 객체가 생성될 때마다 별도의 메모리에 할당되며, 각 객체는 자신만의 고유한 값을 가집니다.
Instance 변수의 특징:
- 각 객체마다 독립적으로 존재
- 객체가 생성될 때 메모리에 할당되고, 해당 객체가 소멸될 때 메모리에서 해제
- 각 객체가 고유한 값을 가짐
Instance 변수 예시:
class Car {
String model; // 각 Car 객체가 고유하게 가지는 변수
Car(String model) {
this.model = model;
}
}
여기서 model
변수는 instance 변수입니다. 각 Car
객체는 자신만의 model
값을 가지며, 다른 객체와 값을 공유하지 않습니다.
3. Static 변수 vs Instance 변수: 차이점 비교
이 두 가지 개념은 서로 다르게 동작하며, 올바르게 이해하고 사용해야 효과적인 코드 작성을 할 수 있습니다.
구분 | Static 변수 | Instance 변수 |
---|---|---|
소속 | 클래스 자체에 속함 | 각 객체(인스턴스)에 속함 |
메모리 할당 | 클래스 로드 시 메모리에 한 번만 할당 | 객체 생성 시마다 별도의 메모리 할당 |
값 공유 | 모든 객체가 동일한 값을 공유 | 각 객체마다 고유한 값을 가짐 |
접근 방법 | 클래스명으로 접근 (예: ClassName.var ) |
객체명으로 접근 (예: object.var ) |
차이점 예시:
class Car {
static int totalCars = 0; // 모든 객체가 공유
String model; // 각 객체마다 고유한 값
Car(String model) {
this.model = model;
totalCars++; // 모든 Car 객체가 공유하는 값
}
}
public class Main {
public static void main(String[] args) {
Car car1 = new Car("Model S");
Car car2 = new Car("Model 3");
System.out.println("Total Cars: " + Car.totalCars); // 출력: 2
System.out.println("Car1 Model: " + car1.model); // 출력: Model S
System.out.println("Car2 Model: " + car2.model); // 출력: Model 3
}
}
이 코드에서 totalCars
는 static 변수이므로 모든 Car
객체가 공유합니다. 반면에 model
은 instance 변수로, 각 객체가 자신의 고유한 값을 가집니다.
4. Static 변수를 사용하는 경우
그렇다면 언제 static 변수를 사용해야 할까요? Static 변수는 공통된 값이나 상태를 관리할 때 매우 유용합니다. 아래는 몇 가지 대표적인 사용 사례입니다.
4.1 전체 객체 수 추적
Static 변수는 특정 클래스의 전체 객체 수를 추적할 때 유용합니다. 위에서 살펴본 예시처럼, Car
클래스에서 totalCars
라는 static 변수를 사용하여 생성된 모든 객체 수를 추적할 수 있습니다.
4.2 상수 관리
상수 값을 관리할 때는 static final
변수를 사용합니다. Static 변수로 선언하여 클래스 자체에서 상수를 공유하고, final로 선언하여 값이 변경되지 않도록 할 수 있습니다.
class Constants {
static final double PI = 3.14159;
}
이렇게 하면 Constants.PI
로 상수에 접근할 수 있고, 프로그램 전반에 걸쳐 동일한 상수를 사용할 수 있습니다.
4.3 공통된 리소스 관리
Static 변수는 데이터베이스 연결, 설정 파일 경로 등 공통된 리소스를 관리할 때도 유용합니다. 이를 통해 프로그램의 모든 인스턴스가 동일한 리소스를 공유할 수 있습니다.
class DatabaseConnection {
static String dbURL = "jdbc:mysql://localhost:3306/mydb";
}
모든 객체가 DatabaseConnection.dbURL
을 통해 동일한 데이터베이스 URL을 사용할 수 있습니다.
5. Static 변수 사용 시 주의사항
Static 변수는 모든 객체가 값을 공유하기 때문에 동시성 문제가 발생할 수 있습니다. 여러 스레드가 동시에 static 변수에 접근해 값을 변경하는 경우, 예상치 못한 결과가 나올 수 있습니다. 이러한 경우에는 스레드 안전성을 고려하여 설계를 해야 합니다.
또한, static 변수는 클래스 로드 시 메모리에 할당되고 프로그램이 종료될 때까지 유지되므로 메모리 관리에 주의해야 합니다. 특히, 크기가 큰 데이터를 static 변수로 관리할 경우 메모리 부족 현상이 발생할 수 있습니다.
결론
Static 변수와 Instance 변수는 객체지향 프로그래밍에서 중요한 개념입니다. Static 변수는 클래스 자체에 속하고 모든 인스턴스가 공유하는 반면, Instance 변수는 각 객체가 고유하게 가지는 변수입니다.
언제 static 변수를 사용해야 할지에 대한 기준은 공통된 상태나 리소스를 관리할 때이며, 이를 잘 활용하면 더 효율적인 코드를 작성할 수 있습니다. 그러나 메모리 관리와 동시성 문제에도 주의해야 합니다.
객체지향 프로그래밍의 기본 개념을 잘 이해하고, 상황에 맞게 static 변수와 instance 변수를 적절히 사용하는 것이 중요합니다.