-
작은 범위에서 큰 범위로는 당옇니 값을 넣을 수 있다.
-
큰 범위에서 작은 범위는 다음과 같은 문제가 발생할 수 있다.
- 소수점 버림
- 오버플로우
-
자바는 기본적으로 가은 타입에 갑을 대입할 수 있다. 그런데 다른 타입에 값을 대입하면 어떻게 될까?
-
int -> long을 비교해보면 long이 int 보다 더 큰 숫자 범위를 표현한다. 작은 범위 숫자 타입에서 큰 범위 수자 타입에 대입을 하면 문제가 되지 않는다. 만약 이런 경우까지 오류가 발생한다면 개발이 너무 불편할 것이다.
-
long -> double의 경우에도 double은 부동 소수점을 사용하기 때문에 더 큰 숫자 범위를 표현한다. 따라서 대입할 수 있다.
-
정리하면 작은 범위에서 큰 범위로의 대입은 자바 언어에서 허용한다. 쉽게 이야기하면 큰 그릇은 작은 그릇에 담긴 내용물을 담을 수 있다.
//intValue = 10
doubleValue = intValue
doubleValue = (double) intValue //형 맞추기
doubleValue = (double) 10 //변수 값 읽기
doubleValue = 10.0 //형변환작은 범위 숫자 타입에서 큰 범위 숫자 타입으로의 대입은 개발자가 이렇게 직접 형변환을 하지 않아도 된다. 이런 과정이 자동으로 일어나기 떄문에 자동 형변환, 또는 묵시적 형변환이라고 한다.
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);
}
}다음 코드의 앞부분에 있는 주석을 풀면 컴파일 오류가 발생한다. int형은 double형보다 숫자의 표현 범위가 작다. 그리고 실수를 표현할 수도 없다. 따라서 이 경우 숫자가 손실되는 문제가 발생할 수 있다. 쉽게 이야기해서 큰 컵에 담긴 물을 작은 컵에 옮겨 담으려고 하니 손실이 발생할 수 있다는 것이다.
하지만 만약 이런 위험을 개발자가 직접 감수하고도 값을 대입하고 싶다면 데이터 타입을 강제로 변경할 수 있다.
형변환은 다음과 같이 변경하고 싶은 데이터 타입을 (int)와 같이 괄호를 사용해서 명시적으로 입력하면 된다.
intValue = (int) doubleValue; //형변환이것을 형(타입)을 바꾼다고 해서 형변환이라고 한다. 영어로는 캐스팅이라 한다. 그리고 개발자가 직접 형변환 코드를 입력한다고 해서 명시적 형변환이라고 한다.
"캐스팅"은 영어 단어 "cast"에서 유래 되었다. "cast"는 금속이나 달느 물질을 녹여서 특정한 형태나 모양으로 만드는 과정을 의미한다.
doubleValue = 1.5
intValue = (int) doubleValue;
intValue = (int) 1.5// doubleValue에 있는 값을 읽는다.
intValue = 1; // (int)로 형변환 한다. intValue에 int형인 숫자 1을 대입한다.형변환 후 출력해보면 숫자 1이 출력되는 것을 확인할 수 있다. 참고로 형변환을 한다고 해서 doubleValue 자체의 타입이 변경되거나 그 안에 있는 값이 변경되는 것은 아니다. doubleValue에서 읽은 값을 형변환 하는 것이다. doubleValue 안에 들어있는 값은 1.5로 그대로 유지된다. 참고로 변수의 값은 대입연산자(=)를 사용해서 직접 대입할 때만 변경된다.
maxIntOver = 2147483648L; //int 최고값 + 1
intValue = (int) maxIntOver; //변수 값 읽기
intValue = (int) 2147483648L; //형변환 시도
intValue = -2147483648;- 결과를 보면 -214783648이라는 전혀 다른 숫자가 보인다. int형은 214783648L를 표현할 수 있는 방법이 없다. 이렇게 기존 범위를 초과해서 표현하게 되면 전혀 다른 숫자가 표현되는데, 이런 현상을 오버플로우라 한다.
- 보통 오버플로우가 발생하는 것 자체가 문제라는 점이다! 오버플로우가 발생했을 떄 결과가 어떻게 되는지 계산하는데 시간을 낭비하면 안된다! 오버플로우 자체가 발생하지 않도록 막아야 한다. 이 경우 단순히 대입하는 변수(intValue)의 타입을 int -> long으로 변경해서 사이즈를 늘리면 오버플로우 문제가 해결된다.
자바에서 계산은 다음 2가지를 기억하자
- 같은 타입끼리의 계싼은 같은 타입의 결과를 낸다.
- int + int는 int를 double + double은 double의 결과가 나온다.
- 서로 다른 타입의 계산은 큰 범위로 자동 형변환이 일어난다.
- int + long은 long + long으로 자동 형변환이 일어난다.
- int + double은 double + double로 자동 형변환이 일어난다.
int -> long -> double
- 작은 범위에서 큰 범위로는 대입할 수 있다.
- 이것을 묵시적 형변환 또는 자동 형변환이라고 한다.
- 큰 범위에서 작은 범위의 대입은 다음과 같은 문제가 발생할 수 있다. 이때는 명시적 형변환을 사용해야 한다.
- 소수점 버림
- 오버플로우
- 연산과 형변환
- 같은 타입은 같은 결과를 낸다.
- 서로 다른 타입의 곗나은 큰 범위로 자동 형변환이 일어난다.