프로그램을 작성하다 보면 “이 변수는 어디까지 사용할 수 있는가?”라는 문제가 자연스럽게 등장한다.
자바에서는 이를 스코프(Scope) 라는 개념으로 명확하게 관리한다. 스코프는 변수의 접근 가능 범위를 의미한다.
변수의 종류
변수는 선언 위치에 따라 다음과 같이 분류된다.
- 지역 변수 (Local Variable)
- 멤버 변수
- 인스턴스 변수
- 클래스 변수
지역 변수란 무엇인가
지역 변수는 말 그대로 특정 지역에서만 사용할 수 있는 변수이다.
여기서 말하는 “지역”이란 변수가 선언된 코드 블록 {} 을 의미한다.
지역 변수의 특징은 다음과 같다.
- 선언된 코드 블록 안에서만 생존한다
- 코드 블록을 벗어나면 즉시 제거된다
- 제거된 이후에는 접근할 수 없다
코드 블록과 변수의 생존 범위
다음 예제를 통해 지역 변수의 스코프를 살펴본다.
Scope1 예제
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); // 컴파일 오류
System.out.println("main m = " + m);
} // m 생존 종료
}
변수 m의 스코프
`m`은 `main {}` 코드 블록 안에서 선언되었다.
따라서 `main {}` 이 시작되는 시점부터 끝날 때까지 생존한다.
`if {}` 블록 안에서도 접근이 가능하다.
이는 내부 블록에서 외부 블록의 변수에 접근하는 것은 허용되기 때문이다.
변수 x의 스코프
`x`는 `if {}` 코드 블록 안에서 선언되었다.
따라서 `if {}` 블록이 끝나는 순간 제거된다.
`if {}` 블록 밖에서 `x`에 접근하려고 하면
`cannot find symbol` 컴파일 오류가 발생한다.
스코프(Scope)의 정의
이처럼 변수가 접근 가능한 범위를 스코프(Scope)라고 한다.
Scope는 영어 그대로 “범위”라는 뜻이다.
- `m`은 `main {}` 전체에서 접근 가능 → 스코프가 넓다
- `x`는 `if {}` 안에서만 접근 가능 → 스코프가 좁다
for 문에서의 스코프
Scope2 예제
package scope;
public class Scope2 {
public static void main(String[] args) {
int m = 10;
for (int i = 0; i < 2; i++) {
System.out.println("for m = " + m);
System.out.println("for i = " + i);
} // i 생존 종료
// System.out.println("main i = " + i); // 컴파일 오류
System.out.println("main m = " + m);
}
}
`for (int i = 0; ...)` 처럼 for 문 초기식에서 선언한 변수 `i`는
for문 코드 블록 안에서만 생존한다.
이 역시 스코프 규칙에 따른 자연스러운 동작이다.
스코프는 왜 필요한가
“변수를 선언한 시점부터 프로그램 끝까지 계속 써도 되지 않을까?”
라는 의문이 들 수 있다. 하지만 스코프는 매우 중요한 역할을 한다.
다음 코드를 보자.
Scope3_1 – 스코프가 넓은 경우
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);
}
}
이 코드는 동작 자체는 문제없다.
하지만 설계 관점에서는 좋은 코드라고 보기 어렵다.
문제점 1: 비효율적인 메모리 사용
`temp`는 `if 블록` 안에서만 필요한 변수이다.
하지만 `main()`이 끝날 때까지 메모리에 유지된다.
불필요한 생존 시간은 메모리 낭비로 이어진다.
문제점 2: 코드 복잡성 증가
`temp`는 임시 변수이다.
그럼에도 `main()` 전체에서 접근 가능하므로,
코드를 읽는 사람은 `temp`의 존재를 계속 의식해야 한다.
실무 코드가 복잡해질수록 이런 변수는 유지보수를 어렵게 만든다.
스코프를 줄인 개선된 코드
Scope3_2 – 필요한 범위로 스코프 제한
package scope;
public class Scope3_2 {
public static void main(String[] args) {
int m = 10;
if (m > 0) {
int temp = m * 2;
System.out.println("temp = " + temp);
}
System.out.println("m = " + m);
}
}
이제 `temp`는 `if 블록` 안에서만 생존한다.
- 메모리를 더 효율적으로 사용한다
- 코드가 단순해진다
- 유지보수가 쉬워진다
while 문과 for 문을 스코프 관점에서 비교
while 문 예제
int sum = 0;
int i = 1;
int endNum = 3;
while (i <= endNum) {
sum += i;
i++;
}
`i`의 스코프는 `main()` 전체이다.
for 문 예제
int sum = 0;
int endNum = 3;
for (int i = 1; i <= endNum; i++) {
sum += i;
}
i의 스코프는 for 문 안으로 제한된다.
어떤 반복문이 더 좋은가
카운터 변수처럼 반복문 내부에서만 사용되는 변수라면
while 문보다 for 문이 더 적절하다.
- 스코프가 좁다
- 실수 가능성이 줄어든다
- 유지보수가 쉬워진다
정리
- 변수는 꼭 필요한 범위에서만 사용하는 것이 좋다
- 스코프를 좁히면 메모리 사용이 효율적이다
- 스코프를 좁히면 코드 가독성과 유지보수성이 좋아진다
좋은 프로그램은 무한한 자유가 있는 프로그램이 아니다.
적절한 제약이 있는 프로그램이다.
'김영한 > 자바 입문' 카테고리의 다른 글
| 배열의 선언과 생성 (0) | 2026.02.09 |
|---|---|
| Scanner (0) | 2026.02.09 |
| 형변환과 오버플로우 (0) | 2026.02.09 |
| 변수 선언과 초기화 (0) | 2026.02.08 |
| 자바란? (0) | 2026.02.08 |