loading
본문 바로가기
Java

[JAVA] static이란 무엇인가!!

by 원쿤짱쿤 2024. 4. 11.
반응형


자바 프로그램에서 오류가 발생된 부분을 찾는 문제를 푸는중..  static으로 선언된 get 메소드로 인해 컴파일러 오류가 발생된 부분이 이해되지 않아서 이것저것 찾아 보았다.

문제를 다 쓰기 귀찮으니 ㅎㅎ.. 간략해서 적는다..

class Person {
    private String name;

    public Person(String val) {
        name = val;
    }

    public static String get() {
        return name;
    }
}

public class Test {
    public static void main(String[] args) {
        Person obj = new Person("kim");
        System.out.println(obj.get());
    }
}

여기서 return name 부분에서 컴파일러 오류가 발생된다

해석을 찾아보니...
" static으로 선언된 메소드는 메모리에 클래스를 위한 공간이 할당되지 않았고 static으로 선언된 메소드에서 메모리가 존재하지도 않는 클래스의 변수 name을 참조하는 것은 불가능 합니다"

뭔말이지?
그래서 이것저것 찾아봤다...!
문장별로 이해해보자!!

문장
'static으로 선언된 메소드는 메모리에 클래스를 위한 공간이 할당되지 않았다'


우선 메모리라는 단어가 나왔으니 메모리 영역에대해서 알아보자

  • 힙(Heap): 동적으로 할당된 메모리를 관리합니다. 객체(인스턴스)들은 힙 메모리에 할당되며, 개발자가 직접 할당하고 해제할 수 있습니다. 인스턴스 변수와 객체를 저장합니다.
  • 스택(Stack): 지역 변수, 매개변수 및 메소드 호출을 관리하는 메모리 영역입니다. 메소드가 호출될 때마다 해당 메소드의 지역 변수와 매개변수가 스택에 생성되며, 메소드가 종료되면 해당 변수들이 스택에서 제거됩니다.
  • 코드(Code) 영역 또는 텍스트(Text) 영역: 프로그램의 실행 코드가 저장되는 영역입니다. 프로그램의 명령어들이 포함된 메모리 영역으로, 읽기 전용입니다. 실행 중인 프로그램의 명령어들이 여기에 저장됩니다.
  • 정적(Static) 영역: 정적 변수와 클래스의 메소드를 저장하는 메모리 영역입니다. 프로그램이 시작될 때 생성되고, 프로그램이 종료될 때까지 유지됩니다. 클래스 수준의 변수와 메소드가 여기에 저장됩니다.


static 으로 선언된 get 메소드는 정적(Static) 영역에 저장된거고 나머지 객체들은 힙(heap)영역에 저장된걸로 생각하면 되겠다.

즉 static으로 선언된 변수와 메소드는 클래스 수준에 속하며, 정적(Static) 영역에 저장되고 이 영역은 프로그램이 시작될 때 생성되고, 프로그램이 종료될 때까지 유지된다. 클래스 수준의 변수와 메소드가 여기에 저장되어 클래스의 인스턴스를 생성하지 않고도 접근할 수 있다.

문장
"static으로 선언된 메소드에서 메모리가 존재하지도 않는 클래스의 변수 name을 참조하는 것은 불가능 합니다"

그러면 공간이 할당되지 않았다는 이유는 알겠는데.
name변수로 반환은 왜 안되는걸까?
이유는 아래와같다.

get() 메소드에서 name 변수를 반환하려고 할 때 오류가 발생하는 이유는 name 변수가 인스턴스 변수이기 때문이다

get() 메소드가 static으로 선언되었다면 클래스 수준에 속하므로, name 변수에 접근할 수 없다.
따라서 name 변수도 static으로 선언되어야 한다

class Person {
    private static String name;

    public Person(String val) {
        name = val;
    }

    public static String get() {
        return name;
    }
}

public class Test {
    public static void main(String[] args) {
        Person obj = new Person("kim");
        System.out.println(obj.get());
    }
}


그러나 name 변수는 각각의 인스턴스마다 다른 값을 가지므로 static으로 선언하면 모든 인스턴스에서 동일한 값을 공유하게 된다!!

올바른 방법은 get() 메소드를 static으로 선언하지 않고, 일반(non-static) 메소드로 선언하여 인스턴스 변수인 name에 접근하는 것이다


올바른 방법

class Person {
    private String name;

    public Person(String val) {
        name = val;
    }

    public String get() {
        return name;
    }
}

public class Test {
    public static void main(String[] args) {
        Person obj = new Person("kim");
        System.out.println(obj.get());
    }
}

인스턴스 메소드는 힙(heap) 영역에 할당됩니다. 인스턴스 메소드는 각 인스턴스에 속하는 동작을 정의하고, 실제로는 각 인스턴스에 따로 존재하는 것이기 때문에 힙(heap) 영역에 저장됩니다.

인스턴스 메소드는 클래스의 각 인스턴스에 속하는 동작을 정의하므로, 메소드 내에서 인스턴스 변수에 직접적으로 접근할 수 있습니다. 따라서 인스턴스 메소드가 호출될 때는 해당 메소드가 속한 인스턴스의 상태를 변경하거나 조회하는 등의 작업을 수행합니다.

'Java' 카테고리의 다른 글

[JAVA] 다형성 왜 쓸까?  (0) 2024.04.10
java) 주석과 세미클론  (0) 2022.02.27
java)5일차 변수  (0) 2022.02.27
java)4일차 -참조  (0) 2022.02.26
Java)3일차  (0) 2022.02.25