[Java] 인스턴스 멤버와 정적 멤버, 정적 멤버안에 정적 멤버만 사용할 수 있는 이유

    클래스로 부터 객체를 여러개 만들수 있는데 클래스 객체마다 모두 같은 데이터를 가지는 데이터가 있을때 모든 객체마다 해당 데이터를 가질 필요가 없다. 공유되는 해당 데이터를 가지는 필드를 한곳에 위치시키고 객체들이 공유 할 수 있게 하면 좋을 것이다.

    자바에서 위 경우를 위해 클래스 멤버를 인스턴스 멤버와, 정적 멤버로 구분해서 선언할 수 있도록 한다.

     

    [정적 멤버]

    인스턴스 멤버는 객체를 생성하고 그 객체를 참조해야 사용할 수 있지만 정적 멤버는 클래스에 고정된 멤버로서 객체를 생성하지 않고 사용할 수 있다. 정적 멤버로 사용하려면 앞에 static을 붙이는데 이때 필드와 메소드 앞에만 붙인다. 왜냐하면 생성자는 객체를 생성하기 위해서 있는 것이기 때문에 무조건 정적 멤버일 수 밖에 없다.

     

    정적 멤버는 자바 메모리 사용영역에서 메소드 영역에 할당되는데 이는 처음 프로그램을 실행 시켰을 때 클래스로더가 클래스 파일을 읽는 시점에서 메소드 영역에 할당되는 것이다.  그래서 사용할때도 객체를 생성하기 전에 클래스 이름과 함께 도트(.) 연산자로 접근할 수 있는 것이다.

    클래스.정적필드;
    클래스.정적메소드();

     

    [인스턴스 멤버와 정적 멤버 메모리 사용영역과 정적 멤버 사용 주의점]

    정적 멤버는 자바 메모리 사용영역에서 메소드 영역에 할당 된다고 했다. 이는 프로그램이 끝날때까지 끝까지 가지고 있는 데이터라는 뜻이다. 클래스로더 시점에 메소드 영역에 할당되는건 정적 필드, 생성자, 정적 메소드 이다. 반대로 인스턴스 멤버 메모리 할당 시점은 객체를 생성할 때이고 인스턴스 필드, 인스턴스 메소드이다. 만약 객체가 여러개 생성된다면 각 객체마다 인스턴스 멤버, 메소드는 각각 계속 생성될 것이다. 그러면 객체를 엄청 많이 생성한다고 했을때 최대한 많이 메소드 영역에 위치시키면 되지 않을까 라고 생각이 들수 있지만 자바 메모리 사용영역에서 힙과 메소드의 가장 큰 차이는 가비지컬렉션의 영향이다. 힙은 가비지 컬렉션으로 정리가 되지만 메소드 영역은 프로그램 끝날때까지 계속 있다. 그러므로 무분별한 정적 멤버 사용은 메모리 효율성을 떨어 뜨릴수 있고, 객체를 아무리 많이 만들지라도 정적 멤버 사용을 최소화 해야 한다.

     

    ex) 정적  메소드 선언시 인스턴스 멤버 사용시 컴파일 에러 발생

    public class ClassName {
        //인스턴스 필드와 메소드
        int field1;
        void method1() {}
    
        //정적 필드와 메소드
        static int field2;
        static void method2() {}
    
        static void method3(int filed2) {
            //this.field1 = 10; //컴파일 에러
            //this.method1(); //컴파일 에러
    
            field2 = filed2; //앞에 this. 사용 불가능 this.은 자신의 객체를 가르키기 때문
            method2();
        }
    }

     

    위 코드에서 클래스로더 시점에 자바 메모리 사용영역에서 생성 되는건 static int filed2와 static void methos2() {} 메소드 이고 ClassName() {} 생성자 함수일 것이다.  

    인스턴스 필드와 메소드인 int field1과 void method1() {} 은 객체 생성된 시점에서 힙 영역에 생길것이다. 메소드 영역에 있는 method1() 함수가 객체가 생성되기 전에는 메모리에 없는 인스턴스 필드와 메소드가 당연히 사용될 수가 없다 그래서 정적 메소드인 method3() 안에서 filed1과 method1을 사용하려고 하면 에러가 나는 것이다. 그러므로 인스턴스 멤버와 메소드를 사용하려면 무조건 인스턴스 메소드로 만들어야 한다.

    filed2를 참조하려고 this. 를 붙이면 에러가 나는데 this. 는 자신 객체대한 참조이기 때문에 사용하려고 하면 에러가 난다.

     

    참고 : 혼자 공부하는 자바 / 신용권  https://www.yes24.com/Product/Goods/74269939 

     

     

    댓글

    Designed by JB FACTORY