Java/문법

스코프, 형변환 간단 정리

JuNo_12 2025. 4. 11. 19:59

스코프: 지역 변수와 범위

변수는 선언된 위치에 따라 지역 변수, 멤버 변수 등으로 나뉩니다. 여기서 지역 변수는 특정 지역, 즉 변수가 선언된 코드 블록({}) 내에서만 사용 가능한 변수를 의미합니다. 지역 변수는 선언된 블록 안에서 생존하며, 블록을 벗어나면 제거되어 접근할 수 없습니다.

변수의 접근 가능한 범위를 스코프(Scope)라고 합니다. 스코프가 넓은 변수는 코드 전체에서 접근 가능하지만, 스코프가 좁은 변수는 특정 블록 내에서만 접근할 수 있습니다.

예를 들어, main() 메서드 내에서 선언된 변수 m은 main() 메서드 전체에서 접근 가능하지만, if() 블록 내에서 선언된 변수 x는 if() 블록 내에서만 접근 가능합니다.

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 m = " + m);
 } //m 생존 종료
}

스코프가 필요한 이유

스코프를 제한함으로써 메모리 사용을 효율적으로 관리하고, 코드의 복잡성을 줄일 수 있습니다.

예를 들어, if 조건이 만족할 때만 사용되는 임시 변수 temp를 main() 코드 블록에 선언하는 대신, if() 블록 내에 선언하면 temp는 if() 블록이 종료될 때 메모리에서 제거되어 메모리 낭비를 줄일 수 있습니다. 또한, temp 변수를 생각해야 하는 범위를 줄여 코드 유지보수성을 높일 수 있습니다.

package scope;
public class Scope3 {
 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);
 }
}

 

형변환: 자동 형변환

자바에서 숫자를 표현할 수 있는 범위는 int < long < double 순입니다. 작은 범위에서 큰 범위로 값을 대입하는 것은 허용됩니다. 예를 들어, int 값을 long 또는 double 변수에 대입하는 것은 문제가 없습니다.

이러한 대입은 자동 형변환(묵시적 형변환)이라고 합니다. 자바는 자동으로 작은 범위의 타입을 큰 범위의 타입으로 변환하여 대입합니다.

package casting;
public class Casting1 {
 public static void main(String[] args) {
 int intValue = 10;
 long longValue;
 double doubleValue;
 longValue = intValue; // int -> long
 System.out.println("longValue = " + longValue);
 doubleValue = intValue; // int -> double
 System.out.println("doubleValue1 = " + doubleValue);
 doubleValue = 20L; // long -> double
 System.out.println("doubleValue2 = " + doubleValue);
 }
}

형변환: 명시적 형변환

큰 범위에서 작은 범위로 값을 대입하는 것은 문제가 발생할 수 있습니다. 예를 들어, double 값을 int 변수에 대입하면 소수점 이하가 버려지거나, 오버플로우가 발생할 수 있습니다. 따라서 자바는 이러한 경우 컴파일 오류를 발생시킵니다.

하지만 개발자가 직접 형변환을 수행하여 값을 대입할 수 있습니다. 이를 명시적 형변환이라고 합니다. 명시적 형변환은 데이터 손실의 위험을 감수하고 타입을 변경하는 것입니다.

package casting;
public class Casting2 {
 public static void main(String[] args) {
 double doubleValue = 1.5;
 int intValue = 0;
 intValue = (int) doubleValue; //형변환
 System.out.println(intValue); //출력:1
 }
}

형변환을 한다고 해서 doubleValue 자체의 타입이 변경되거나 그 안에 있는 값이 변경되는 것은 아닙니다. doubleValue 에서 읽은 값을 형변환 하는 것입니다.

형변환과 오버플로우

형변환 시 작은 타입이 표현할 수 있는 범위를 넘어서면 오버플로우가 발생합니다. 오버플로우는 마치 시계가 한 바퀴 돈 것처럼 다시 처음부터 시작하는 현상입니다. 오버플로우가 발생하는 것 자체가 문제이므로, 오버플로우가 발생하지 않도록 주의해야 합니다.

package casting;
public class Casting3 {
 public static void main(String[] args) {
 long maxIntValue = 2147483647; //int 최고값
 long maxIntOver = 2147483648L; //int 최고값 + 1(초과)
 int intValue = 0;
 intValue = (int) maxIntValue; //형변환
 System.out.println("maxIntValue casting=" + intValue);
 intValue = (int) maxIntOver; //형변환
 System.out.println("maxIntOver casting=" + intValue);
 }
}

계산과 형변환

형변환은 대입뿐만 아니라, 계산을 할 때도 발생합니다. 자바에서 계산은 다음과 같은 규칙을 따릅니다.

  • 같은 타입끼리의 계산은 같은 타입의 결과를 냅니다.
  • 서로 다른 타입의 계산은 큰 범위로 자동 형변환이 일어납니다.
package casting;
public class Casting4 {
 public static void main(String[] args) {
 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
 }
}