1. 여러 인스턴스에서 공통으로 사용하는 변수 (static 변수)
- 인스턴스가 생성될 때 만들어지는 변수가 아니라, 처음 프로그램이 메모리에 로딩될 때 메모리 할당
- = 클래스 변수, 정적 변수
- 인스턴스 생성과 상관없이 사용할 수 있으므로 클래스 이름으로 직접 참조(ex. Employee.serialNum)
2. static 변수 선언과 사용하기
static int num;
studentLee.num = 10000;
Employee.java
public class Employee {
private static int serialNum = 1000;
private int employeeId;
private String employeeName;
private String department;
public Employee() {
serialNum++;
this.employeeId = serialNum;
}
public int getEmployeeId() {
return employeeId;
}
public void setEmployeeId(int employeeId) {
this.employeeId = employeeId;
}
public String getEmployeeName() {
return employeeName;
}
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
public static int getSerialNum() {
return serialNum;
}
// 이 메서드는 클래스에 속한 정적(static) 메서드 -> 사용할 때 클래스 이름을 통해 호출돼야 함
// static 메서드는 인스턴스 생성과 무관하게 호출 가능 (인스턴스가 0개여도 static 메서드 호출 가능)
/*
public static void setSerialNum(int serialNum) {
Employee.serialNum = serialNum;
}
여기서 SerialNum은 외부에서 조정되면 안되므로 setter는 지워준다.
*/
}
EmployeeTest.java
public class EmployeeTest {
public static void main(String[] args) {
Employee employeeLee = new Employee();
employeeLee.setEmployeeName("이순신");
System.out.println(employeeLee.getSerialNum());
Employee employeeKim = new Employee();
employeeKim.setEmployeeName("김유신");
System.out.println(employeeLee.getEmployeeId());
System.out.println(employeeKim.getEmployeeId());
}
}
- static 변수는 인스턴스에서 공통으로 사용하는 영역이다.
3. 변수의 유효 범위와 메모리
- static 변수는 프로그램이 메모리에 있는 동안 계속 그 영역을 차지하므로, 너무 큰 메모리를 할당하는 것은 좋지 않음
- 클래스 내부의 여러 메서드에서 사용하는 변수는 멤버 변수로 선언하는 것이 좋은데,
멤버 변수가 너무 많으면 인스턴스 생성 시 쓸모없는 메모리가 할당 되므로 상황에 적절하게 변수를 사용해야 한다.
4. static 응용 - 싱글톤 패턴(singleton pattern)
1. 싱글톤 패턴
: 디자인 패턴 중 하나로, 프로그램에서 인스턴스가 단 한 개만 생성돼야 하는 경우 사용하는 디자인 패턴이다.
2. 싱글톤 패턴으로 Company 객체 구현하기
// <싱글톤 패턴>
public class Company {
// 외부에서 마음대로 Company를 new할 수 없도록 생성자를 1개 만들어 준다. (생성자를 private로 선언하면 외부에서 인스턴스 생성 불가)
private Company() {}
// 싱글톤 패턴은 인스턴스가 유일, 즉 단 하나이다. 이 하나뿐인 인스턴스는 Company 클래스 내부에 만들어준다.
private static Company instance = new Company(); // 단 하나만 있을거니까 static으로 만듬.
// 보통의 경우에는 test class(?)에서 instance를 생성하고 메서드 호출할 수 있음.
// 따라서 이 메서드는 static으로 선언해주어야 한다.
// 그래야 외부에서 클래스 이름으로 메서드 호출해서 사용 가능
public static Company getInstance() {
if (instance == null) {
instance = new Company();
}
return instance;
}
// 여기까지가 싱글톤 패턴 끝~
}

5. static 응용 문제
- 아래 문제에 맞게 Car와 CarFactory 코드를 구현해라.
CarFactoryTest.java
public class CarFactoryTest {
public static void main(String[] args) {
CarFactory factory = CarFactory.getInstance();
Car mySonata = factory.createCar();
Car yourSonata = factory.createCar();
System.out.println(mySonata.getCarNum()); //10001 출력
System.out.println(yourSonata.getCarNum()); //10002 출력
}
}
Car.java
public class Car {
private static int num = 10000;
private int carNum;
public Car() {
num++;
setCarNum();
}
public void setCarNum() {
this.carNum = num;
}
public int getCarNum() {
return this.carNum;
}
}
CarFactory.java
public class CarFactory {
private CarFactory() {};
private static CarFactory instance= new CarFactory();
public static CarFactory getInstance() {
return instance;
}
public Car createCar() {
Car newCar = new Car();
return newCar;
}
}
설명) 코드를 처음 짤 때부터 헷갈렸다... 우선 "이 공장에서 생산되는 자동차는 제작될 때마다 고유의 번호가 부여된다." 라는 문장을 봤을 때 고유의 번호를 static으로 선언을 해야 하는데, 이 고유의 번호 변수 이름을 num이라고 했을 때, num을 Car 클래스에서 선언할 지, CarFactory 클래스에서 선언할 지부터 고민이 되었다. 왜냐면 "이 공장에서 생산되는" 이니까 이 공장에서 생산되는 자동차만 고유 번호가 부여되는 것 같기 때문이었다. 그래도 우선 차 번호니까 Car 클래스에서 선언을 해주었다.
그리고 Car가 만들어질 때마다 num을 증가해주고, setCarNum 함수를 호출해서 각 인스턴스별로 차 번호가 지정되게 해주었다.
자동차 공장은 유일한 객체이므로 CarFactory 내에서 private로 생성자를 넣어주었다.
* 본 게시물은 패스트캠퍼스 "한 번에 끝내는 Java/Spring 웹 개발 마스터 초격차 패키지" 강의를 수강한 내용을 바탕으로 작성했습니다.
'Java' 카테고리의 다른 글
Java(1) 리터럴, 변수, 오버플로우, 언더플로우, 형변환 (0) | 2024.08.05 |
---|---|
[Java] 배열 (0) | 2024.07.11 |
[Java] 객체 자신을 가리키는 this (0) | 2024.07.07 |
접근 제어 지시자(access modifier)와 캡슐화 (0) | 2024.07.05 |
생성자(constructor)와 생성자 오버로딩 (0) | 2024.07.05 |