JAVA/about java

[variables] 지역변수, 클래스변수, 인스턴스 변수

dev_rosieposie 2023. 8. 20. 18:46

Goal

  1. 변수의 종류에 대해 알아본다
  2. 객체지향 프로그램이 메모리를 사용하는 방식에 대해 알아본다
  3. 각 변수들이 메모리에 적재되는 위치에 대해 알아본다

변수의 종류 

변수가 선언된 위치에 따라 구분된다.

  • 지역 변수 - 클래스 이외의 영역( 메소드, 생성자, 초기화 블럭)에 위치
  • 멤버 변수 - 클래스 영역 내 위치
    • 클래스 변수
    • 객체(인스턴스) 변수
      • 객체 속성 변수
      • 객체 참조 변수
    • 종단(final) 변수
public class test {

    // 인스턴스 변수
    int iv;

    // 클래스 변수
    static int cv;

    void method() {
        // 지역 변수
        int lv; 
    }
}

지역 변수

  • stack 영역에 저장
  • 메서드 내에서 선언되며 메서드 내에서만 사용할 수 있는 변수입
  • 메서드가 실행될 때 메모리를 할당 받으며 메서드가 끝나면 소멸

클래스 변수 

  • static 영역에 저장
  • static 키워드
  • 일반변수와 달리 객체이름을 통해 접근 불가 → 클래스이름을 통해서 접근
  • 처음 JVM이 실행되어 클래스가 메모리에 올라갈 때 ~ 프로그램이 종료될 때까지 유지
  • 클래스가 여러 번 생성되어도 Static 변수는 처음 딱 한 번만 생성됨
  • 동일한 클래스의 모든 객체들에 의해서 공유됨
  • this 키워드 사용 불가
    •  this는 호출 당시 실행 중인 객체를 가리키는 레퍼런스인데 static메소드는 객체가 생성되지 않은 상황에서도 호출이 가능하기 때문이다.

인스턴스 변수

  • heap 영역에 저장
    • GC의 대상
  • 인스턴스가 생성될 때 생성됨 = 객체 생성 시마다 매번 새로운 변수가 생성됨
    • 그렇기 때문에 인스턴스 변수의 값을 읽어오거나 저장하려면 인스턴스를 먼저 생성해야 하며, 인스턴스 별로 다른 값을 가질 수 있으므로, 각각의 인스턴스마다 고유의 값을 가져야할 때는 인스턴스 변수로 선언해야 한다.
  • 클래스 변수와 달리 공유되지 않음

객체 속성 변수

  • 기본 자료형(int, float, char, byte 등)의 값을 가지는 변수
  • call by value - 변수의 값이 복사(변수 자체가 아닌 변수가 저장한 값을 복제)되어 전달 

객체 참조 변수

  • 생성된 객체를 지정하는 변수
  • call by reference - 객체에 대한 참조(reference) 즉, 객체가 생성 저장된 주소(address)를 가진다

final 변수

  • final를 사용하여 변수를 지정하면 사용하여 선언
  • final이 붙은 변수는 단 한번 초기화 할 수 있으며 그 이후에는 그 값을 변경할 수 없음
  • 변수이름 사용의 관례상 final변수는 대문자를 많이 사용

객체 지향 프로그램의 메모리 사용 방식

코드 실행 영역 스태틱(Static) 영역
스택(Stack) 영역 힙(Heap) 영역

각 변수들이 메모리에 적재되는 위치

public static class StaticClassTest{
    static int classVar = 10;
    int instanceVar = 28;
}

public static void main(String[] args){
    StaticClassTest staticClassTest1 = new StaticClassTest();
    StaticClassTest staticClassTest2 = new StaticClassTest();

    System.out.println("1. "+staticClassTest1.classVar+", "+staticClassTest1.instanceVar);
    System.out.println("2. "+staticClassTest2.classVar+", "+staticClassTest2.instanceVar);

    staticClassTest1.classVar = 12;
    staticClassTest1.instanceVar = 40;

    System.out.println("1. "+staticClassTest1.classVar+", "+staticClassTest1.instanceVar);
    System.out.println("2. "+staticClassTest2.classVar+", "+staticClassTest2.instanceVar);
}

 

결과

1. 10, 28
2. 10, 28
1. 12, 40
2. 12, 28

 

=> staticTest1, staticTest2 두 객체를 생성했을 때 new()로 생성된 두 객체가 각각 Heap에 할당되고 각 객체를 가리키는 staticTest1변수와 staticTest2변수가 stack에 생성된다.

인스턴스 변수 지역변수는 객체가 생성될 때마다 Stack영역에 매번 새로 생성되지만 클래스 변수 Static Area에 한 개만 생성되고 하나의 영역을 공유한다.

 

 

 

참고

https://www.devkuma.com/docs/java/member-variable/#%EB%A7%B4%EB%B2%84-%EB%B3%80%EC%88%98

https://itmining.tistory.com/20

https://sujinhope.github.io/2021/03/03/Java-%ED%81%B4%EB%9E%98%EC%8A%A4%EB%B3%80%EC%88%98,-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EB%B3%80%EC%88%98-%EC%B0%A8%EC%9D%B4(Static%EB%B3%80%EC%88%98%EC%99%80-Non-Static%EB%B3%80%EC%88%98)