
스코프(Scope)는 변수의 생존 범위, 즉 변수를 선언한 블록({}) 안에서만 변수가 살아있고 사용할 수 있음을 의미한다.
지역 변수를 선언하면 그 변수는 선언된 블록이 끝나는 순간 제거된다.
public class ScopeExample {
public static void main(String[] args) {
int score = 90; // score는 main 블록 전체에서 유효하다.
if (score >= 60) {
int bonus = 10; // bonus는 if 블록 안에서만 유효하다.
System.out.println("합격, 보너스: " + bonus);
}
// System.out.println(bonus); // 오류 발생: bonus는 스코프를 벗어남
System.out.println("최종 점수: " + score);
}
}
score는 main 블록 전체에서 접근할 수 있다. bonus는 if 블록 안에서만 사용할 수 있고, 블록이 끝나면 제거된다. 변수를 꼭 필요한 곳에서만 선언해야 한다.
예를 들어, 임시로 사용할 변수를 블록 밖에 선언하면 불필요하게 메모리를 차지하고, 유지보수 시 신경 써야 할 변수가 늘어난다.
public class ScopeBad {
public static void main(String[] args) {
int score = 85;
int temp = 0; // 불필요하게 스코프가 넓다.
if (score >= 60) {
temp = score + 5;
System.out.println("임시 점수: " + temp);
}
System.out.println("최종 점수: " + score);
}
}
위 코드는 temp가 if 블록에서만 필요한데, main 전체에서 접근 가능하다.
아래처럼 스코프를 줄이는 것이 더 효율적이다.
public class ScopeGood {
public static void main(String[] args) {
int score = 85;
if (score >= 60) {
int temp = score + 5; // 필요한 블록 안에 선언
System.out.println("임시 점수: " + temp);
}
System.out.println("최종 점수: " + score);
}
}
이렇게 하면 temp는 if 블록이 끝나면 제거되므로 메모리를 절약하고 코드도 단순해진다.
// while문
int sum = 0;
int i = 1;
while (i <= 3) {
sum += i;
i++;
}
System.out.println("합계 = " + sum);
i는 while문이 끝난 후에도 여전히 살아있다. // for문
int sum = 0;
for (int i = 1; i <= 3; i++) {
sum += i;
}
System.out.println("합계 = " + sum);
i는 for문 안에서만 유효하고, 반복문이 끝나면 제거된다. 반복 횟수를 세는 변수처럼 특정 블록 안에서만 필요한 경우에는
for문을 사용하는 것이 스코프를 좁히는 데 더 유리하다.
Java에서는 서로 다른 타입끼리 값을 대입하거나 계산할 때 형변환(Casting)이 일어난다.
작은 범위 → 큰 범위로 대입할 때는 자동으로 형변환이 된다.
int score = 90;
long bigScore = score; // int → long
double average = score; // int → double
System.out.println(bigScore); // 90
System.out.println(average); // 90.0
이 경우 개발자가 따로 형변환을 적지 않아도 된다.
큰 범위 → 작은 범위로 대입할 때는 값이 손실될 수 있기 때문에 반드시 명시적으로 형변환을 해야 한다.
double average = 89.7;
int intScore = (int) average; // double → int
System.out.println(intScore); // 89 (소수점 버림)
long big = 2147483648L; // int 범위 초과
int small = (int) big;
System.out.println(small); // -2147483648 (오버플로우)
따라서 큰 값을 작은 타입으로 바꿀 때는 항상 주의해야 한다.
계산 과정에서도 형변환이 발생한다.
int a = 3;
int b = 2;
int result1 = a / b; // int / int → int 결과 (1)
double result2 = a / b; // int / int → int 결과 후 double로 변환 (1.0)
double result3 = (double) a / b; // double / int → double 결과 (1.5)
System.out.println(result1);
System.out.println(result2);
System.out.println(result3);