[Java] 스코프(Scope)와 형변환(Casting)

손주현·2025년 4월 4일

Java 기초

목록 보기
8/13
post-thumbnail

자바에서 변수는 선언된 범위(스코프) 안에서만 유효하며,
서로 다른 타입 간 대입에는 형변환이 필요하다. 이번 글에서는 이 두 개념을 정리한다.


1. 스코프 (Scope)

1-1. 지역 변수의 생존 범위

  • 변수는 선언된 {} 블록 안에서만 유효하다. 해당 블록을 벗어나면 변수는 제거되고 접근할 수 없다.
public static void main(String[] args) {
    int m = 10; // main 전체에서 유효

    if (true) {
        int x = 20; // if 블록 내부에서만 유효
        System.out.println(m); // 가능
        System.out.println(x); // 가능
    }

    // System.out.println(x); // 오류: x는 스코프 밖
    System.out.println(m); // 가능
}

1-2. for 문과 스코프

  • for문 안에서 선언한 변수는 해당 for 블록 안에서만 사용 가능하다.
for (int i = 0; i < 3; i++) {
    System.out.println(i); // 가능
}
// System.out.println(i); // 오류: i는 for문 밖

왜 스코프가 필요할까?

  • 메모리 낭비 줄임
  • 코드 가독성 향상
  • 유지보수에 유리

변수는 꼭 필요한 범위 내에서만 사용하는 것이 좋다.

  • ❌ 잘못된 예
int temp = 0;

if (m > 0) {
    temp = m * 2;
}
  • ✅ 좋은 예
if (m > 0) {
    int temp = m * 2;
}

2. 형변환 (Casting)

2-1. 묵시적(자동) 형변환

  • 작은 타입 → 큰 타입으로 변환은 자동으로 처리된다.
int intValue = 10;
long longValue = intValue;
double doubleValue = intValue;
  • int → long → double 은 값의 손실이 없기 때문에 자동으로 변환된다.
  • 이처럼 묵시적 형변환은 컴파일 시점에 처리되며, .class 파일에는 해당 형변환 정보가 명확하게 기록된다.

즉, 자바 컴파일러가 소스 코드를 바이트코드로 변환할 때 형변환을 JVM이 인식할 수 있도록 명확하게 삽입한다.

2-2. 명시적(강제) 형변환

  • 큰 타입 → 작은 타입으로 변환하려면 명시적으로 변환해야 한다.
double d = 1.5;
int i = (int) d;  // 소수점 버려짐 → i = 1

형변환과 오버플로우

형변환을 할 때 만약 작은 숫자가 표현할 수 있는 범위를 넘어서면 어떻게 될까?

long big = 2147483648L;  // int 최대값 초과
int small = (int) big;

System.out.println(small);  // 출력: -2147483648
  • 2147483648은 int 범위를 넘는 값 → 형변환 시 비트 앞쪽(부호비트 포함)이 잘려 나감
  • 그 결과 int의 최소값(-2,147,483,648) 이 된다

왜 이런 일이 생길까?

  • 컴퓨터는 메모리 공간이 고정되어 있으므로,
    큰 타입에서 작은 타입으로 변환할 경우 비트 수가 줄어들면서 앞쪽 비트들이 손실된다.
    이는 2의 보수 표현 방식에 의해 음수로 해석될 수 있다.

오버플로우가 발생해도 컴파일 에러는 없다

  • 형변환 자체는 문제가 없기 때문에 컴파일러는 에러를 내지 않는다.
    하지만 결과는 예기치 않게 나올 수 있으므로, 반드시 값을 확인하거나 조건을 체크해야 한다.

오버플로우는 눈에 보이지 않고, 경고 없이 발생하기 때문에 항상 주의해야 한다!


3. 계산 시 형변환

  • 계산 과정에서도 자동 형변환이 발생할 수 있다.
  • 같은 타입끼리 계산 → 결과도 같은 타입
  • 다른 타입끼리 계산 → 큰 타입으로 자동 형변환
int div1 = 3 / 2;
System.out.println("div1 = " + div1); //1

double div2 = 3 / 2;
System.out.println("div2 = " + div2); //1.0

double div3 = 3.0 / 2;
System.out.println("div3 = " + div3); //1.5

double div4 = (double) 3 / 2;
System.out.println("div4 = " + div4); //1.5

int a = 3;
int b = 2;
double result = (double) a / b;
System.out.println("result = " + result); //1.5
구분설명예시
자동 형변환작은 타입 → 큰 타입, 문제 없음int → long → double
명시적 형변환큰 타입 → 작은 타입, 개발자 책임(int) 1.5 → 1 (소수 손실)

작은 컵에서 큰 컵은 OK, 큰 컵에서 작은 컵은 흘러넘칠 수 있다!

profile
Clarinetist.dev

0개의 댓글