tuter77

Java : 객체간의 협력(static, 변수 메모리) 본문

JavaStudy

Java : 객체간의 협력(static, 변수 메모리)

tuter77 2023. 1. 29. 19:42

*static이면 객체 생성이 필요없이 메인이 호출가능하다.

 

 객체 간의 협력

- 객체 지향 프로그램에서 객체 간에는 협력이 이루어짐.(메세지가 오간다.)

- 협력을 위해서는 필요한 메시지를 전송하고 이를 처리하는 기능이 구현되어야 한다.

- 매개 변수로 객체가 전달되는 경우가 발생한다.

 

구현된 협력 기능 함수들은 ctrl 을 누른상태로 클릭하면 해당 클래스의 메소드로 갈 수 있다.

 

 여러 인스턴스에서 공통으로 사용하는 변수 선언 - static 변수

 

▷ 공통으로 사용하는 변수가 필요한 경우

- 여러 인스턴스가 공유하는 기준 값이 필요한 경우

- 학생마다 새로운 학번 생성

- 카드회사에서 카드를 새로 발급할 때마다 새로운 카드 번호를 부여

- 회사에 사원이 입사할 때마다 새로운 사번이 필요한 경우.

 

데이터 영역 메모리

static 변수 < 공유 < 인스턴스 A, 인스턴스 B, 인스턴스 C

 

▷ static 변수 선언과 사용하기

 

예시 : static int seialNum;

- 인스턴스가 생성될 때 만들어지는 변수가 아닌, 처음 프로그램이 메모리에 로딩될 때 메모리를 할당한다.(이 때에 만들어진다.)

- 클래스 변수, 정적 변수라고도 한다.(vs 인스턴스 변수)

- 인스턴스 생성과 상관 없이 사용 가능하므로 클래스 이름으로 직접 참조한다.(예시 : Student_serialNum = 100;)

static 변수는 앞선 Heap메모리가 아닌, code(명령어 집합) 메모리와 Data(또는 상수) 영어 메모리 중 Data영역 메모리에 생성된다. 프로그램이 다 끝나고 메모리가 업로드 되는 순간 삭제된다.

 

예시)

public class Employee {

public static int serialNum = 1000; //static 변수 선언.

 

private int employeeId;

private String employeeName;

private String department;

 

public int getEmployeeId() { //우클릭 source에서 getter/setter 자동생성.

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;

}

}

위 예시에서 인스턴스들이 공동으로 사용할 static 변수를 생성했다.

 

public class EmployeeTest {

public static void main(String[] args) {

Employee employeeLee = new Employee();

employeeLee.setEmployeeName("이순신");

System.out.println(employeeLee.serialNum);

 

Employee employeeKim = new Employee();

employeeKim.setEmployeeName("김유신");

employeeKim.serialNum++;

 

System.out.println(employeeLee.serialNum);

System.out.println(employeeKim.serialNum);

//2개의 인스턴스가 1개의 메모리를 공유한다. > lee와 kim이 하나의 serialNum을 공유.

}

}

 

인스턴스 2개 (lee와 kim을 생성하여 static 변수인 serialNum을 공유하는지 출력해보았더니, 

위와 같이 같은 변수를 공유하고 있음을 알 수 있었다.

쉽게 정리해보면 

 

데이터 영역      |     스택메모리      |     힙 메모리  

                 

serialNum         >    employeeLee  >    employeeLee  인스턴스

                         >    employeeKim  >    employeeKim  인스턴스

 

이 형태를 띄고 있음을 알 수 있다.

위의 예시 과정에서 System.out.println(employeeLee.serialNum); 이 구문은 밑줄이 그어지는데, 이는 static변수는 클래스 이름을 참조하라는 뜻이다.

static 메서드는 인스턴스 생성과 무관하게 클래스 이름으로 호출될 수 있다.

인스턴스 생성 전에 호출 될 수 있으므로 static 메서드 내부에서는 인스턴스 변수를 사용할 수 없다.(인스턴스 변수는 메모리의 순서상 static이전에 생성되지 않았기 때문)

반면 일반 메서드에선 static 메서드를 사용하는건 문제가 없다.(메모리의 순서 때문)

 

▷ 변수의 유효 범위와 메모리

- 변수의 유효 범위(scope)와 생성과 소멸(life cycle)은 각 변수의 종류마다 다르다.

- 지역 변수, 멤버 변수, 클래스 변수는 유효범위와 life cycle, 사용하는 메모리도 다르다. 

 

- static 변수는 프로그램이 메모리에 있는 동안 계속 그 영역을 차지하므로 너무 큰 메모리를 할당하는 것은 좋지 않다.

- 클래스 내부의 여러 메서드에서 사용하는 변수는 멤버변수로 선언하는 것이 좋고, 멤버 변수가 너무 많으면 인스턴스 생성시 쓸데없는 메모리가 할당된다.  

 

오늘은 static 변수를 중심으로 메모리가 어떻게 할당되는지, 사용은 어떤식으로 해야하는지를 공부했다. 

블로그에 다 담지못하는 실습 예시들이 있지만, 글이 너무 길어지고 난잡해지는것같아 빼게되었다. 

오늘 공부한것 처럼 클래스내에서 사용되는 지역변수, 멤버변수, static 변수의 각 차이점을 잘 이해했고, 각 객체간에 변수와 메소드를 활용해 협력하는 것도 잘 이해한것 같아 뿌듯하다.

 

위 내용은 2022.12.26에 공부한 내용입니다.

링크 : https://dudwls3278.tistory.com/24