참고: 김영한의 자바 입문 강의 참고 내용
지역 변수와 스코프
- 변수는 선언한 위치에 따라 지역 변수, 멤버 변수(클래스 변수, 인스턴스 변수)와 같이 분류된다.
- 지역 변수는 특정 지역에서만 사용할 수 있는 변수로, 그 특정 지역({})을 벗어나면 사용할 수 없다.
- 즉, 지역 변수는 자신이 선언된 코드 블록({}) 안에서만 생존하고, 그 블록을 벗어나면 제거된다고 생각하면 된다. 제거되었기 때문에 접근할 수 없다.
예제
public static void main(String[] args) {
int m = 10; // 변수 m은 main 함수 내에서 생존
if (true) {
int n = 20; // 변수 n은 if문 내에서만 생존
System.out.println(m);
System.out.println(n);
} // 변수 n 제거
System.out.println(m);
System.out.println(n); // 오류, 변수 n에 접근 불가. (에러 메세지 "java: cannot find symbol")
}
지역 변수는 본인의 코드 블록 안에서만 생존할 수 있다. 자신의 코드 블록 안에서는 얼마든지 접근이 가능하다. 자신의 코드 블록을 벗어나게 되면 제거되기 때문에 더 이상 접근이 불가하다.
이렇듯, 변수의 접근 가능한 범위를 스코프(=Scope)라 한다.
위의 예제에서 int m은 비교적 넓은 스코프를, int n은 좁은 스코프를 가지고 있다.
스코프가 존재하는 이유
왜 복잡하게 접근 범위라는 개념을 만들어서 사용하고 있는 것인가?
예제
public static void main(String[] args) {
int m = 10;
int temp = 0; // if문 내에서 사용하기 위한 임시 변수
if (m > 0) {
temp = m * 2;
System.out.println("temp: " + temp );
}
System.out.println("m: " + m);
}
위 예제는 좋은 코드라고 보기 어렵다. 이유는 임시 변수 temp는 if 조건 내에서 임시로 잠깐 사용하는 변수일 뿐인데, temp가 main() 코드 블록에 선언되어 있어서 다음과 같은 문제가 발생한다.
- 비효율적인 메모리 사용:
temp는 if 블록 내에서만 필요한 변수이지만, main() 코드 블록이 종료될 때까지 메모리에 유지된다. 따라서 불필요한 메모리가 낭비된다. - 코드 복잡성 증가:
좋은 코드는 군더더기 없는 단순한 코드이다. temp는 if 코드 블록 내에서만 필요하기 때문에 해당 범위 내에서만 사용되면 된다. 그리고 만약 if 코드 블록 안에 temp를 선언했다면 if문이 끝나고 난 뒤에는 temp를 고려해줄 필요가 없다. (고려해야 할 변수가 하나 줄어듦) 즉, 위의 예제는 코드를 유지보수 할 때 m은 물론이고 temp까지 계속 신경써야 한다. (temp의 스코프가 불필요하게 넓다)
위 예제를 수정한다면?
public static void main(String[] args) {
int m = 10;
if (m > 0) {
int temp = 0;
temp = m * 2;
System.out.println("temp: " + temp );
} // temp 생존 종료
System.out.println("m: " + m);
}
정리
- 변수는 꼭 필요한 범위로 한정해서 사용하는 것이 좋다. 메모리를 효율적으로 사용하고 더 유지보수하기 좋은 코드를 만들 수 있다.
- 좋은 프로그램은 무한한 자유가 있는 프로그램이 아니라, 적절한 제약이 있는 프로그램이다.
추가 (반복문 스코프)
for (int i = 0; i < 2; i++) {
int m = 1;
}
while (true) {
int n = 1;
}
반복문이라 동일 블록을 여러번 실행할 것이고, 그럼 위처럼 변수를 정의하면 `Variable 'n' is already defined in the scope` 와 같은 에러가 발생하지 않을까? 라고 생각했으나, 위 예제는 문제 없이 잘 실행된다.
각 반복마다 새로운 블록이 시작되므로, 이전 루프의 변수 n, m은 더 이상 유효하지 않고 새로운 n, m 변수가 새로 선언된다. 따라서 변수 중복 선언 에러가 발생하지 않는다.
하지만 다음과 같이 하면 문제가 발생한다.
int num = 1;
while (true) {
int num = 2; // 여기서 에러 발생: 변수 'num'이 이미 while 밖의 더 큰 스코프에서 정의됨
}
'프로그래밍 언어 > Java' 카테고리의 다른 글
[Java] 배열 생성 방법 (0) | 2024.08.16 |
---|---|
[Java] 형변환과 오버플로우, 계산시 형변환 (0) | 2024.08.13 |
[Java] 문자열 비교 (equals) (0) | 2024.08.09 |
[Java] 문자열 + 숫자 (0) | 2024.08.09 |
[Java] 변수 타입 정리(자주 사용되는 것과 사용되지 않는 것) (0) | 2024.08.08 |