Study

[JAVA/자바] 스코프

_유니 2023. 4. 19. 13:48

 

지역 변수와 스코프

변수는 선언한 위치에 따라 지역 변수, 멤버 변수(클래스 변수, 인스턴스 변수)와 같이 분류된다.

 

지역 변수는 이름 그대로 특정 지역에서만 사용할 수 있는 변수라는 뜻이다.

그 특정 지역을 벗어나면 사용할 수 없다. 여기서 말하는 지역이 바로 변수가 선언된 코드 블록( { } )이다.

지역 변수는 자신이 선언된 코드 블록( { } ) 안에서만 생존하고, 자신이 선언된 코드 블록을 벗어나면 제거된다.

따라서 이후에는 접근할 수 없다.

 

package scope;

public class Scope1 {

    public static void main(String[] args) {
        int m = 10; // m 생존 시작

        if (true) {
            int x = 20; // x 생존 시작
            System.out.println("if m = " + m); // 블록 내부에서 블록 외부는 접근 가능
            System.out.println("if x = " + x);
        } // x 생존 종료

        // System.out.println("main x = " + x); // 오루, 변수 x에 접근 불가
        System.out.println("main m = " + m);
    } // m 생존 종료
}

* int m

- int m은 main{ }의 코드 블록 안에서 선언되었다. 따라서 변수를 선언한 시점부터 main{ }의 코드 블록이 종료될 때까지 생존한다.

- if{ } 블록 내부에서도 외부 블록에서 선언된 m에 접근할 수 있다. 쉽게 이야기해서 생존 범위만 맞으면 다 접근할 수 있다.

* int x

- int x는 if{ } 블록 안에서 선언되었다. 따라서 변수를 선언한 시점부터 if{ ]의 코드 블록이 종료될 때까지 생존한다.

- if{ } 내부에서는 자신의 범위에서 선언한 x에 당연히 접근할 수 있다.

- if{ } 코드 블록이 끝나버리면 x는 제거된다. 따라서 더는 x에 접근할 수 없다.

따라서 이후에 접근하면 cannot find symbol이라는 변수 이름을 찾을 수 없다는 컴파일 오류가 발생한다.

 

정리하자면 지역 변수는 본인의 코드 블록 안에서만 생존한다. 그리고 자신의 코드 블록 안에서는 얼마든지 접근할 수 있다. 하지만 자신의 코드 블록을 벗어나면 제거되기 때문에 접근할 수 없다.

 

이렇게 변수의 접근 가능한 범위를 스코프(Scope)라 한다 참고로 Scope를 번역하면 범위라는 뜻이다.

int m은 main{ } 전체에서 접근할 수 있기 때문에 스코프가 넓고,

int x는 if{ } 코드 블록 안에서만 접근할 수 있기 때문에 스코프가 짧다.

 

package scope;

public class Scope2 {

    public static void main(String[] args) {
        int m = 10;

        for (int i = 0; i < 2; i++) { // 블록 내부, for문 내
            System.out.println("for m = " + m); // 블록 내부에서 외부는 접근 가능
            System.out.println("for i = " + i);
        } // i 생존 종료

        // System.out.println("main i = " + i); // 오류, i에 접근 불가
        System.out.println("main m = " + m);
    }
}

for문으로 바뀐 것을 제외하면 앞의 예제와 비슷한 예제이다.

for문의 경우 for문 앞에서 초기식에 직접 변수를 선언할 수 있다.

그리고 이렇게 선언한 변수는 for문 코드 블록 안에서만 사용할 수 있다.

 

스코프 존재 이유

package scope;

public class Scope3_1 {

    public static void main(String[] args) {
        int m = 10;
        int temp = 0;

        if (m > 0) {
            temp = m * 2;
            System.out.println("temp = " + temp);
        }
        System.out.println("m = " + m);
    }
}

조건이 맞으면 변수 m의 값을 2배 증가해서 출력하는 코드이다.

여기서 2배 증가한 값을 저장해 두기 위해 임시 변수 temp를 사용했다. 그런데 이 코드는 좋은 코드라고 보기는 어렵다.

왜냐하면 임시 변수 temp는 if 조건이 만족할 때 임시로 잠깐 사용하는 변수이다.

그런데 임시 변수 temp main( ) 코드 블록에 선언되어 있다. 이렇게 되면 다음과 같은 문제가 발생한다.

 

- 비효율적인 메모리 사용 : temp는 if 코드 블록에서만 필요하지만, main( ) 코드 블록이 종료될 때까지 메모리에 유지된다.

따라서 불필요한 메모리가 낭비된다. 만약 if 코드 블록 안에 temp를 선언했다면 자바를 구현하는 곳에서 if 코드 블록의 종료 시점에 이 변수를 메모리에서 제거해서 더 효율적으로 메모리를 사용할 수 있다.

- 코드 복잡성 증가 : 좋은 코드는 군더더기 없는 단순한 코드이다. temp는 if 코드 블록에서만 필요하고, 여기서만 사용하면 된다.

만약 if 코드 블록 안에 temp를 선언했다면 if가 끝나고 나면 temp를 전혀 생각하지 않아도 된다. 머릿속에서 생각할 변수를 하나 줄일 수 있다.

그런데 지금 작성한 코드는 if 코드 블록이 끝나도 main( ) 어디서나 temp를 여전히 접근할 수 있다.

누군가 이 코드를 유지보수 할 때 m은 물론이고 temp까지 계속 신경 써야 한다. 스코프가 불필요하게 넓은 것이다.

지금은 코드가 매우 단순해서 이해하는데 어려움이 없겠지만 실무에서는 코드가 매우 복잡한 경우가 많다.

 

정리

- 변수는 꼭 필요한 범위로 한정해서 사용하는 것이 좋다. 변수의 스코프는 꼭 필요한 곳으로 한정해서 사용하자.

메모리를 효율적으로 사용하고 더 유지보수하기 좋은 코드를 만들 수 있다.

- 좋은 프로그램은 무한한 자유가 있는 프로그램이 아니라 적절한 제약이 있는 프로그램이다.