본문 바로가기

Java

[자바 / Java] 멤버변수와 클래스변수, 지역변수

전역변수 (멤버변수, 클래스변수)  vs 지역변수

  구분 선언위치 초기화  접근 메모리영역 생명주기





멤버
변수
클래스 블럭 내
선언
자동 초기화 클래스 내부의 모든 메서드에서 사용 가능 Heap 객체가 생성될 때
할당
객체 소멸시 소멸
클래스변수 클래스 블럭 내
static 키워드를
붙여 선언
static 프로그램이 시작 시 할당~종료 시
소멸
객체 생성없이
사용가능

지역변수
메서드 블럭 내
선언
초기화 필수
(수동초기화,
자동초기화 X)
선언된 블록 내부에서만 사용 가능 Stack 블록 내부 실행 종료 시 소멸

전역변수는 클래스 블록 안에 선언되며, 해당 클래스 내의 모든 메서드에서 접근 가능합니다. 전역변수는 자동 초기화가 되므로, 초기화하지 않아도 기본값으로 초기화됩니다. 전역변수는 Heap 메모리 영역에 저장되며, 프로그램이 시작되면 생성되고 프로그램이 종료될 때까지 유지됩니다.

지역변수는 메서드 블록 안에 선언되며, 해당 블록 내에서만 접근 가능합니다. 지역변수는 선언 후 수동으로 초기화해야 하며, 초기화하지 않은 변수를 사용하면 컴파일 오류가 발생합니다. 지역변수는 Stack 메모리 영역에 저장되며, 해당 블록 내부에서 실행이 종료되면 소멸됩니다.

 

 

public class Cat {
   // 전역변수
   String name;
   int age;
   static String breed; // 클래스변수

   public void printInfo() {
      // 지역변수
      String message = "My cat's name is " + name + ", she is " + age + " years old, and she is a " + breed;
      System.out.println(message);
   }
}

 

 

위의 예제에서, "Cat" 클래스는 이름(name), 나이(age)와 같은 전역변수를 가지고 있습니다. 이 변수들은 클래스의 어디서든지 사용할 수 있습니다.

또한, "breed"는 static 예약어를 사용하여 클래스변수로 선언되었습니다. 클래스변수는 클래스에서 공유되는 변수이기 때문에 클래스 내의 어디서든 사용할 수 있습니다.

마지막으로, "printInfo()" 메소드 내에서 String message와 같이 지역변수를 선언할 수 있습니다. 지역변수는 해당 메소드 블록 내에서만 사용할 수 있습니다.

따라서, 위의 예제에서 name과 age는 전역변수, breed는 클래스변수, message는 지역변수입니다.

 

 

지역변수, 전역변수는 각각 언제 사용해야 할까?

1. 멤버변수

전역변수는 클래스 영역에 선언되는 변수로서, 클래스 내부의 모든 메소드에서 공통적으로 사용할 수 있습니다.

따라서 전역변수는 다른 메소드에서도 값을 유지하면서 사용할 필요가 있을 때 유용합니다. 하지만 전역변수는 메모리가 할당될 때부터 프로그램이 종료될 때까지 유지되므로, 메모리 낭비가 발생할 수 있습니다. 또한 전역변수를 다른 메소드에서 함부로 변경하면 오류를 발생시킬 가능성도 있습니다.

 

2. 지역변수

지역변수 지역변수는 메소드 내부에서 선언되는 변수로서, 해당 메소드 내부에서만 사용할 수 있습니다.

지역변수는 메소드가 실행될 때 메모리에 할당되고, 메소드가 종료될 때 메모리에서 제거됩니다. 이러한 특성 때문에 지역변수는 메모리를 효율적으로 사용할 수 있습니다. 또한 지역변수는 해당 메소드 내부에서만 사용되기 때문에 다른 메소드에서 함부로 변경될 우려가 없습니다.

 

3. 클래스변수

클래스변수 클래스변수는 전역변수와 마찬가지로 클래스 영역에 선언되는 변수이며, static 키워드를 사용하여 선언됩니다. 클래스변수는 해당 클래스의 인스턴스들 사이에서 값을 공유할 수 있으며, 인스턴스를 생성하지 않고도 사용할 수 있습니다. 인스턴스마다 변수가 생성되는 것을 방지하여 메모리를 절약할 수 있기 때문에, 값을 유지해야하는 상황에서 유용합니다. 클래스의 구조를 나타내는데 사용되는 상수나 플래그 등을 저장할 때 사용됩니다.

하지만 클래스변수 역시 전역변수와 같이 프로그램 전체에서 메모리를 사용하기 때문에, 낭비를 줄이기 위해서는 적절한 사용이 필요합니다.

 

 

public class Cat {
  // 전역변수, 인스턴스마다 개별적으로 메모리 공간을 할당받는다.
  String name;
  int age;

  // 클래스변수, 클래스 내 모든 인스턴스가 공유하는 메모리 공간을 사용한다.
  static int numberOfCats = 0;

  public Cat(String name, int age) {
    // 지역변수, 해당 메소드 내에서만 사용 가능하며, 메소드가 종료되면 메모리에서 해제된다.
    String nickname = "Kitty";
    this.name = name;
    this.age = age;
    numberOfCats++; // 클래스 변수는 인스턴스 생성 시마다 증가된다.
  }

  public void meow() {
    System.out.println(name + " is meowing!");
  }

  public static void main(String[] args) {
    Cat cat1 = new Cat("Luna", 3);
    Cat cat2 = new Cat("Tiger", 5);

    System.out.println("Number of cats: " + numberOfCats); // 클래스변수는 모든 인스턴스에서 공유되므로 2 출력

    cat1.meow(); // Luna is meowing!
    cat2.meow(); // Tiger is meowing!
  }
}

 

위 코드에서 name과 age는 전역변수로, 인스턴스가 생성될 때마다 개별적인 메모리 공간을 할당받습니다. numberOfCats는 클래스변수로, 모든 인스턴스가 공유하는 메모리 공간을 사용합니다. nickname은 Cat 클래스의 생성자에서 사용되는 지역변수로, 해당 메소드 내에서만 사용 가능하며, 메소드가 종료되면 메모리에서 해제됩니다.

main 메소드에서 Cat 클래스의 인스턴스인 cat1과 cat2를 생성하면서 numberOfCats 변수는 각각 1씩 증가합니다. cat1.meow()와 cat2.meow()는 각 인스턴스의 name값을 출력합니다.

 

따라서, 변수의 범위와 메모리 사용량을 고려하여 적절한 변수를 사용해야 합니다. 전역변수와 클래스변수는 값의 유지와 공유가 필요한 경우에 사용하며, 지역변수는 메소드 내에서만 필요한 값일 경우에 사용합니다. 그러나 메모리 사용량을 최소화하기 위해서는 지역변수를 적극 활용하는 것이 좋습니다.

 

 

 

 

 

 

Reference

 

https://www.javatpoint.com/difference-between-global-variable-and-local-variable-in-java

 https://www.geeksforgeeks.org/difference-between-static-and-non-static-variables-in-java/  https://www.baeldung.com/java-variable-scope