본문 바로가기
JAVA/객체지향

자바 static 변수 뜻, 의미, 사용방법 그리고 유효범위

by 스코리아 2023. 8. 17.

안녕하세요, 스코리아입니다.

오늘은 자바 static 변수의 의미와 선언/구현 방법에 대해서 알아보고 어떠한 주의사항이 있는지 알아보겠습니다.

 

static 변수란?

  • 여러 인스턴스에서 공통으로 사용하는 변수를 선언할 때 static 변수를 사용합니다.
  • 즉, 모든 인스턴스가 static 변수를 공유하는 형태로 작동합니다.

static 변수

  • [예] 그러면 공통으로 사용하는 변수가 필요한 경우는 언제일까요?
  • 여러 인스턴스가 공유하는 기준값이 필요한 경우
  • 학생마다 새로운 학번을 생성해야 하는 경우
  • 회사에 신입사원이 입사할 때 새로운 사번이 필요한 경우
  • 카드 회사에서 카드를 새로 발급할 때마다 새로운 카드 번호를 발급해야 하는 경우

 

static 변수 선언, 사용방법

public class Student {
	static int serialNum; // static 변수 선언
}
  • static 변수는 인스턴스가 생성될 때 만들어지는 변수가 아닌, 처음 프로그램이 메모리에 로딩될 때 메모리를 할당합니다.
  • 클래스 변수, 정적변수라고도 합니다.
  • 인스턴스 생성과 상관없이 사용 가능하므로 아래와 같이 클래스 이름으로 직접 참조가 가능합니다.
Student.serialNum = 100; // 클래스이름으로 직접 참조

 

 

static 변수 예제 - 구현하기

  • Employee.java 파일을 만들고, serialNum 변수 static 변수로 지정하여 인스턴스가 생성될 때마다 1씩 증가되도록 구현해 봅시다. 
  • 그리고 serialNum 변수를 1씩 증가한 후, 사원 번호인 employeeId에 저장하여 고유한 사원 번호로 만들어봅시다.
  • 즉, 회사원이 입사할 때마다 새로운 사번이 부여되는 시스템입니다.
public class Employee {
    private static int serialNum = 1000; // static 변수

    private int employeeId; // 멤버 변수
    private String employeeName;

    public Employee()
    {
        employeeId = ++serialNum;
    }

    public static int getSerialNum() {
        return serialNum;
    }

    public static void setSerialNum(int serialNum) {
//        int i = 0; // 지역 변수
//        this.employeeName = "Lee";  //오류발생 => 인스턴스 호출전이기 때문에
        Employee.serialNum = 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;
    }
}
  • ++serialNum 은 serialNum을 우선 1을 더한 뒤, employeeId에 대입한다는 뜻입니다. (serialNum++ 은 serialNum을 employeeId에 먼저 대입 후 1을 더합니다)
  • serialNum, employeeId, employeeName 변수 모두 private로 선언하여, 외부에서 참조되지 못하도록 막았고, 모두 getter, setter를 구현해 두었습니다. (왜 public이 아니라 private 로 선언했을까요? 정보은닉 참고하기: https://skorea6.tistory.com/10 )
  • serialNum은 static 변수입니다. static 메소드인 setSerialNum()은 인스턴스 생성전에 호출될 수 있으므로, 메소드 내부에서는 인스턴스 변수를 사용할 수 없습니다. 즉, this.employeeName과 같은 멤버변수(인스턴스 변수)를 가져오는 행위는 불가합니다.

 

static 변수 예제 - 테스트하기

public class EmployeeTest {
    public static void main(String[] args) {
        Employee employeeLee = new Employee();
        employeeLee.setEmployeeName("이순신");
        System.out.println(Employee.getSerialNum());

        Employee employeeKim = new Employee();
        employeeKim.setEmployeeName("김유신");
        System.out.println(Employee.getSerialNum());

        System.out.println(employeeLee.getEmployeeName() + "," + employeeLee.getEmployeeId());
        System.out.println(employeeKim.getEmployeeName() + "," + employeeKim.getEmployeeId());

        System.out.println(Employee.getSerialNum());
        Employee.setSerialNum(1003);
        System.out.println(Employee.getSerialNum());
    }
}

static 예제 - 테스트 실행결과

  • static 변수와 메소드는 인스턴스 변수, 메소드와 다르게, 클래스이름으로 직접 참조가 가능합니다. 즉, 인스턴스 생성과 무관하게(인스턴스 생성을 하지 않아도) 클래스 이름으로 호출할 수 있습니다. 
// [static 변수 특징] 클래스 이름으로 직접 참조하기
System.out.println(Employee.serialNum); // 참조로 호출
System.out.println(Employee.getSerialNum()); // getter 로 호출
  • 위 코드와 같이, 참조로 호출할 경우, 현재 serialNum이 private으로 막아두었기 때문에, 오류가 뜰 것입니다.
  • 그러므로, 클래스 이름으로 직접 참조하는 방법으로 getter 인 getSerialNum()으로 호출하여 사용할 수 있습니다.

 

 

변수의 유효 범위와 메모리

  • 변수의 유효 범위(scope)와 생성, 소멸(life cycle)은 각 변수의 종류마다 다릅니다.
  • 지역변수, 멤버변수, 클래스 변수는 유효범위와 생성과 소멸, 사용하는 메모리도 모두 다릅니다. 차이점을 알아보겠습니다

변수의 유효 범위와 메모리

  • 멤버 변수의 경우 멤버변수나 메소드가 private이 아니면, employeeLee 인스턴스를 활용하여 employeeLee.employeeName이나 employeeLee.getEmployeeName()과 같이 참조 변수로 다른 클래스에서 사용이 가능합니다.
  • static 변수의 경우 멤버변수나 메소드가 private이 아니면, Employee 클래스 이름을 직접 사용하여 Employee.serialNum이나 Employee.getSerialNum()으로 다른 클래스에서 사용이 가능합니다.

 

 

static 사용 시 주의사항

  • static 변수는 프로그램이 메모리에 있는 동안 계속 그 영역을 차지합니다. 그러므로 너무 큰 메모리를 할당하면 좋지 않습니다.
  • 클래스 내부의 여러 메소드에서는 사용하는 변수는 static이 아닌 멤버 변수로 선언해야 합니다.
  • 멤버 변수가 너무 많으면 인스턴스 생성 시 쓸데없는 메모리가 사용됩니다.
  • 즉, 공통으로 사용하는 변수가 필요할 때만 static을 사용하는 등, 상황에 따라 적절하게 변수를 사용해야 합니다.

 


지금까지 자바(Java) static 변수의 의미와 사용방법, 주의사항과 변수의 유효범위에 대해서 폭넓게 알아보았습니다.

읽어주셔서, 감사합니다.