필요한 내용만 정리.
유지/보수하기 좋은 코드를 짜기 위해 꼭 알아야 한다.
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);
}
}
위 코드는 좋은 코드라고 보기는 어렵다. 왜냐하면 임시 변수 temp 는 if 내에서만 임시로 잠깐 사용하는 변수인데, main() 코드 블록에 선언되어 있다. 이렇게 되면 다음과 같은 문제가 발생한다.
temp 는 if 코드 블록에서만 필요하지만, main() 코드 블록이 종료될 때 까지 메모리 에 유지된다. 따라서 불필요한 메모리가 낭비된다.if 코드 블록 안에 temp 를 선언했다면 자바를 구현하 는곳에서 if 코드블록의 종료시점에 이 변수를 메모리에서 제거해서 더 효율적으로 메모리를 사용할 수 있다. temp 는 if 코드 블록에서만 필요하고, 여기서 만 사용하면 된다. 만약 if 코드블록 안에 temp 를 선언했다면 if 가 끝나고 나면 temp 를 전혀 생각하지 않아도된다. 머리 속에서 생각할 변수를 하나 줄일 수 있다. 그런데 지금 작성한 코드는 if 코드블록이 끝나도 main() 어디서나 temp 를 여전히 접근할 수 있다. 누군가 이 코드를 유지보수 할 때 m 은 물론이고 temp 까지형(타입)을 바꾼다고 해서 형변환이라 한다. 영어로는 캐스팅(Casting)이라 한다.
int long double작은 범위에서 큰 범위로 대입은 허용한다.
int < long < double
하지만 결국 대입하는 형(타입)을 맞추어야 하기 때문에 개념적으로는 다음과 같이 동작한다.
이렇게 앞에 (double) 과 같이 적어주면 int 형이 double 형으로 변한다. 이렇게 형이 변경되는 것을 형변환이라 한다.
작은 범위 숫자 타입에서 큰 범위 숫자 타입으로의 대입은 개발자가 이렇게 직접 형변환을 하지 않아도 된다. 이런 과정 이 자동으로 일어나기 때문에 자동 형변환, 또는 묵시적 형변환이라 한다.
큰 범위에서 작은 범위 대입은 명시적 형변환이 필요하다.
package casting;
public class Casting2 {
public static void main(String[] args) {
double doubleValue = 1.5;
int intValue = 0;
//intValue = doubleValue; //컴파일 오류 발생
intValue = (int) doubleValue; //형변환
System.out.println(intValue);
intValue = doubleValue //컴파일 오류 발생
형변환은 다음과 같이 변경하고 싶은 데이터 타입을 (int) 와 같이 괄호를 사용해서 명시적으로 입력하면 된다.
intValue = (int) doubleValue; //형변환
//doubleValue = 1.5
intValue = (int) doubleValue;
intValue = (int) 1.5; //doubleValue에 있는 값을 읽는다.
intValue = 1; //(int)로 형변환 한다. intValue에 int형인 숫자 1을 대입한다.
참고로 형변환을 한다고 해서 doubleValue 자체의 타입이 변경되거나 그 안에 있는 값이 변경되는 것은 아니다.
doubleValue 에서 읽은 값을 형변환 하는 것이다. doubleValue 안에 들어있는 값은 1.5 로 그대로 유지된다.
작은 숫자가 표현할 수 있는 범위 넘어서면?
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); //출력:2147483647
intValue = (int) maxIntOver; //형변환
System.out.println("maxIntOver casting=" + intValue); //출력:-2147483648 }
}
/*
maxIntValue casting=2147483647
maxIntOver casting=-2147483648
*/
long maxIntValue = 2147483647 를 보면 int 로 표현할 수 있는 가장 큰 숫자인 2147483647 를 입력했다. 이경우 int 로 표현할 수 있는 범위에 포함되기 때문에 다음과 같이 long ➡️int 로 형변환을 해도 아무런 문제가 없다.long maxIntOver = 2147483648L 를 보면 int 로 표현할 수 있는 가장 큰 숫자인 2147483647 보 다 1큰 숫자를 입력했다. 이 숫자는 리터럴은 int 범위를 넘어가기 때문에 마지막에 L 을 붙여서 long 형을 사용해야 한다. 이 경우 int 로 표현할 수 있는 범위를 넘기 때문에 다음과 같이 long ➡️int 로 형변환하면 문제가 발생한다.-2147483648 이라는 전혀 다른 숫자가 보인다. int 형은 2147483648L 를 표현할 수 있는 방 법이 없다. 이렇게 기존 범위를 초과해서 표현하게 되면 전혀 다른 숫자가 표현되는데, 이런 현상을 오버플로우라 한다.intValue )의 타입을 int ➡️long 으로 변경해서 사이즈를 늘리면 오버플로우 문제가 해결된다.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
} }
두 가지만 기억하기.
int + int 는 int 를, double + double 은 double 의 결과가 나온다.int + long 은 long + long 으로 자동 형변환이 일어난다.int + double 은 double + double 로 자동 형변환이 일어난다.int div1 = 3 / 2; //int / int
int div1 = 1; //int / int이므로 int타입으로 결과가 나온다.
double div2 = 3 / 2; //int / int
double div2 = 1; //int / int이므로 int타입으로 결과가 나온다.
double div2 = (double) 1; //int -> double에 대입해야 한다. 자동 형변환 발생
double div2 = 1.0; // 1(int) -> 1.0(double)로 형변환 되었다.
double div3 = 3.0 / 2; //double / int
double div3 = 3.0 / (double) 2; //double / int이므로, double / double로 형변환이 발생한
다.
double div3 = 3.0 / 2.0; //double / double -> double이 된다.
double div3 = 1.5;
double div4 = (double) 3 / 2; //명시적 형변환을 사용했다. (double) int / int
double div4 = (double) 3 / (double) 2; //double / int이므로, double / double로 형변
환이 발생한다.
double div4 = 3.0 / 2.0; //double / double -> double이 된다.
double div4 = 1.5;