[JAVA] static (01.20)

늘보·2025년 1월 20일

Java

목록 보기
16/17
post-thumbnail

메모리 구조

메서드 영역

메서드 영역은 프로그램의 모든 영역에서 공유하며, 공통의 데이터를 관리한다.

  • 클래스 정보: 바이트 코드, 메서드, 생성자 코드 등의 실행 코드를 담고 있다.
  • Static: static 변수를 보관한다.
  • 객체 생성 시 필드는 각자 다른 값을 넣어야 하기 때문에 데이터 메모리를 따로 할당해야 하지만 메서드는 동일하기 때문에 메서드 영역에서 관리된다.

스택(Stack) 영역

스택 영역은 지역변수, 연산결과, 메서드 호출 등을 포함한다.

  • 스택 프레임: 메서드를 호출할 때마다 쌓이며, 메서드 종료시 삭제된다.
    ❗스택 영역은 쓰레드 수 만큼 생성된다.

힙(Heap) 영역

힙 영역은 객체(인스터스)와 배열이 생성되는 영역이다.

  • GC (가비지 컬렉션)이 이루어지는 영역이다. 따라서 더 이상 사용되지 않으면 GC에 의해 제거된다.

💡 클래스 변수 ➡︎ 인스턴스 변수 ➡︎ 지역 변수 | 시간 순서

  • 지역 변수는 메서드 종료시 제거 (스택 영역)
  • 인스턴스 변수는 GC 발생 후 제거 (힙 영역)
  • 클래스 변수는 프로그램 종료 시 제거 (메서드 영역)

Static

static 키워드를 사용하면 공용으로 함께 쓰는 변수를 만들 수 있다.

  • static은 클래스명.변수명으로 사용한다.
  • static 변수는 인스턴스 영역에 생성되지 않고 메서드 영역에서 관리한다.

❗static이 없는 변수를 인스턴스 변수라고 하며 인스턴스 변수는 객체가 생성될 때마다 독립적으로 할당된다.

AnimalMain.java

package static1.ex2;

public class AnimalMain {

    public static void main(String[] args) {

        Animal animal1 = new Animal("기린");
        System.out.println("동물의 총 수는: " + animal1.count);

        Animal animal2 = new Animal("사자");
        System.out.println("동물의 총 수는: " + animal2.count);

        Animal animal3 = new Animal("코끼리");
        System.out.println("동물의 총 수는: " + animal3.count);

    }
}


Animal.java

package static1.ex2;

public class Animal {
    public String name;
    public int count;

    public Animal(String name) {
        this.name = name;
        count ++;
    }

}

위 코드에서의 count 변수static 키워드 없이 작성했기 때문에 해당 변수는 각 객체(animal1, animal2, animal3)의 인스턴스 필드독립적으로 존재하게된다. 즉, count++을 하더라도 자신의 count 변수만을 증가시키게 된다.


💡 따라서 위와 같은 경우 static 키워드를 이용해 공용으로 데이터를 다룬다.

Animal Main.java

package static1.ex2;

public class Animal Main {

    public static void main(String[] args) {

        Animal animal1 = new Animal("기린");
        System.out.println("동물의 총 수는: " + Animal.count);

        Animal animal2 = new Animal("사자");
        System.out.println("동물의 총 수는: " + Animal.count);

        Animal animal3 = new Animal("코끼리");
        System.out.println("동물의 총 수는: " + Animal.count);

    }
}

Animal.java

package static1.ex2;

public class Animal {
    public String name;
    public static int count;

    public Animal(String name) {
>         this.name = name;
        count ++;
    }

}


클래스 변수(정적 변수, static 변수) 접근법

  • 인스턴스를 통해 접근

    인스턴스에 간 후 static을 확인하면 메서드 영역을 통해 값을 가지고 온다.
    ❗즉, 형태만 인스턴스 접근처럼 보이고 실제는 클래스를 통해 접근하는 것과 같다.
    ❗인스턴스를 통해 접근하는 것은 인스턴스의 변수에 접근하는 것처럼 오해할 수 있기 때문에 사용하지 않는 것이 좋다.


  • 클래스를 통해 접근

메서드 static

정적 변수처럼 인스턴스 생성없이 클래스명을 통해 호출할 수 있다.

  • 클래스 내부 기능을 사용할 때 static이 붙은 메서드 혹은 정적 변수사용할 수 있다.
  • 클래스 내부 기능을 사용할 때 인스턴스 메서드 혹은 인스턴스 변수는 사용불가하다.
  • 다른 곳에서는 static 사용 가능

static은 클래스로 접근하기 때문에 참조값이 없이 바로 접근할 수 있게된다. 즉, 위와 같이 메서드 영역에 있는 Data클래스에 바로 접근하여 변수를 사용한다.

반면, 힙 역역의 필드객체를 생성(인스턴스 생성)을 해야 만들어지는 인스턴스 변수이기 때문에 static이 사용할 수 없게 된다.

인스턴스(객체)의 경우 참조값을 통해 클래스 내부를 확인하고 static을 만나면 메서드 영역을 통해 값을 가져오기 때문에 static에 접근할 수 있게된다.


메서드 static 활용

  • 간단한 메서드로 끝나는 유틸리티성 메서드인 경우 사용한다.
  • 매개변수 값만 가지고 계산하는 경우 사용한다. (ex> sum, average, max, min)
  • 정적 메서드를 여러번 호출할 때에는 import를 통해 한번만 선언하고 사용한다. (import static.클래스명.메소드명)

📌 static 메서드의 대표 예시로는 main()이 있다.
➡︎ main문에 함수를 만들 때 모두 static으로 만들어야 가능하다. (위에서 언급한 개념)

profile
누워만 있지 말고 제발 뭐라도 하자.

0개의 댓글