Java

static 변수

hyomee2 2024. 7. 7. 05:12

 

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 변수는 인스턴스에서 공통으로 사용하는 영역이다.

cf. 힙메모리는 동적 메모리

 

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 웹 개발 마스터 초격차 패키지" 강의를 수강한 내용을 바탕으로 작성했습니다.