[Java] static

박채은·2022년 11월 3일
0

Java

목록 보기
10/30

Problem

Github에 올린 질문/답변

이때 당시에는, "클래스(static) 메서드에서는 인스턴스 변수가 접근 불가하다!"를 공식처럼 외워서 이런 궁금증이 생겼었다.
이 질문을 통해 알게 된 점을 정리해보았다.

클래스(static) 메서드에서는 인스턴스 변수가 접근 불가하다!

static 메서드는 컴파일이 완료되고 나서 메모리에 할당되기 때문에 프로그램이 실행(런타임)될 때부터 사용이 가능하다.
그에 비해, 인스턴스 변수는 런타임 중 인스턴스가 생성되었을 때부터 사용이 가능하다.

즉, static 메서드를 사용할 때, 해당 인스턴스 변수가 존재하는지 확신할 수 없다.
(인스턴스 변수가 존재할 수도 있고, 존재하지 않을 수도 있다.)
따라서 static 메소드나 static 내부 클래스에서는 인스턴스 멤버를 사용할 수 없다!

이것은 "동일한 클래스 내에서의 상황"을 기준으로 한 것이다!

1) 서로 다른 클래스인 경우, static 메서드라도, 인스턴스를 생성했다면 인스턴스 멤버를 사용할 수 있다.

public class Test {
    public static void main(String[] args) {
        System.out.println(Car.user); //  클래스 변수 출력
        // 아직 인스턴스화되기 전이기 때문에, 생성자가 호출되지 않아 "김채은"이 출력된다.
        
        Car car1 = new Car(); // 인스턴스 생성
        System.out.println(car1.wheelNum); // 인스턴스 멤버 사용
        System.out.println(car1.model);
    }
}

class Car {
    // 인스턴스 변수
    public int wheelNum = 4;
    public String model = "A";
    // 클래스 변수
    public static String user="김채은";

    // 생성자
    public Car() {
        user="박채은";
    }
}

처음에는 Test 내부의 main 함수도 static 함수니까 내부에 아예 인스턴스 변수를 사용하면 안 되나?라고 생각했다.
근데 그러면 모든 인스턴스 변수들은 어떻게 사용하지? 라는 의문이 들었다.

이때 중요한 것은 "클래스(static) 메서드에서는 인스턴스 변수가 접근 불가하다!"동일한 클래스 내부의 static 메서드와 인스턴스 멤버 사이인 경우를 기준으로 한 것이라는 것이다.

위의 코드처럼 서로 다른 클래스인 경우에는, static인 main 함수에서 Car 클래스를 인스턴스화하기만 했다면, 당연하게 Car 클래스 내부의 인스턴스 변수도 생성이 되었고 인스턴스 변수를 참조할 수 있다.


public class Overloading {
    public static void main(String[] args) {
        Shape shape1 = new Shape();
    }

    class Shape{
        public void area(){
            System.out.println("넓이");
        }
        public void area(int r){
            System.out.println("원 넓이 = " + 3.14*r*r);
        }
        public void area(int w, int h){
            System.out.println("직사각형 넓이 = "+ w*h);
        }
        public void area(double b, double h){
            System.out.println("삼각형 넓이 = "+ b*h*0.5);
        }
    }
}

이렇게 코드를 작성하면, 'com.codestates.seb.calculator.Overloading.this' cannot be referenced from a static context 오류가 발생한다.

필드에 static을 붙이지 않으면 인스턴스 변수가 되는 것처럼, 내부 클래스에 static을 붙이지 않으면 인스턴스 내부 클래스가 된다. Shape이라는 인스턴스 내부 클래스를 현재 static 메서드인 main 메서드에서 참조하고 있으므로, 해당 에러가 발생하게 된 것이다.

즉, Shape이 main 메서드가 속한 클래스의 내부 클래스이기 때문이다.

이처럼 Shape 클래스를 Overloading의 내부 클래스가 아니라, 따로 외부 클래스로 두면 오류는 해결된다.

public class Overloading {
    public static void main(String[] args) {
        Shape shape1 = new Shape();
    }
    
}
class Shape{
        public void area(){
            System.out.println("넓이");
        }
        public void area(int r){
            System.out.println("원 넓이 = " + 3.14*r*r);
        }
        public void area(int w, int h){
            System.out.println("직사각형 넓이 = "+ w*h);
        }
        public void area(double b, double h){
            System.out.println("삼각형 넓이 = "+ b*h*0.5);
        }
}

💡 참고
https://whatisthenext.tistory.com/37

0개의 댓글