안녕하세요. J4J입니다.
이번 포스팅은 형 변환에 대해 적어보는 시간을 가져보려고 합니다.
형 변환이란?
형 변환이라고 하는 것은 자료형에 저장되어 있는 값들을 다른 형태의 자료형에 값을 집어 넣는 것 입니다.
※ 자료형에 대해 모르신다면? [Java] 자바기초 - 자료형
다음 코드로 예를 들어 봅시다.
package transform;
public class Example {
public static void main(String[] args) {
int intVal = 32;
long longVal = intVal;
System.out.println("intVal값: " + intVal);
System.out.println("longVal값: " + longVal);
}
}
자료형 중 정수형에 속하는 가장 대표적인 int와 long을 예시로 들었습니다.
main에서 가장 첫번째 줄을 보시면 int로 선언한 intVal 값에 32를 집어 넣습니다.
이후로 long으로 선언한 longVal값에 이미 선언된 intVal값을 집어 넣습니다.
이 상황을 생각해보시면 위에서 말씀드린 형 변환의 개념과 동일하다고 느껴지시지 않으신가요?
형 변환의 개념을 다시 본다면 자료형에 저장되어 있는 값들을(intVal) 다른 형태의 자료형(longVal)에 값을 집어 넣는 것 이라고 생각할 수 있습니다.
정말 간단하죠?
형 변환에서는 한 가지 명확하게 알고 가셔야 될 것이 있는데 그건 바로 자료형들간의 대소관계입니다.
위에 링크를 걸어둔 자료형 포스팅을 보시면 제가 실수형에 대해 설명하면서 실수형은 정수형보다 더 크다고 말씀드린 것을 확인할 수 있습니다.
이걸 기반으로 대소관계를 명확히 해보면 byte < short < int < long < float < double 이라고 명시할 수 있습니다.
어? 그러면 boolean, char, String은 형 변환이 안되는 것인가요?
이 대답은 No 입니다.
우선 boolean과 String은 이번 포스팅에서는 형 변환이 안된다에 Yes라고 말할 수도 있습니다.
이 말이 무슨의미냐면, 이 포스팅에서 설명할 내용들로는 형 변환이 불가능하지만 추후에 말씀드릴 Wrapper클래스를 이용한다면 형 변환이 가능합니다.
char는 왜 대소관계에서 제외되었을까요?
그 이유는 char는 음수값을 포함하지 않는 2byte 정수형이기 때문에 관계가 명확하지 않아 표현할 수 없었을 뿐입니다.
그리고 이런 형 변환에는 두 가지의 개념이 포함되어 있습니다.
바로 Promotion과 Casting이라는 개념입니다.
Promotion
Promotion이라고 하는 거는 자동 형 변환 이라는 의미를 가집니다.
자동 형 변환이라고 하는 것은 위에서 말씀드린 대소관계에서 더 작은 타입에 저장되어 있는 값이 큰 타입에 집어 넣어질 때 변환되는 것을 말합니다.
다음 코드를 한번 확인해 봅시다.
int보다 더 큰 float에다가 값을 집어 넣으려 할 때는 문제가 되지 않지만 double보다 더 작은 long에다가 값을 집어 넣으려 할때는 에러가 발생되고 있습니다.
그리고 자세히 보시면 정상적으로 동작하는 코드는 위에서 예시를 보여준 것과 비슷하다고 느끼실 수 있습니다.
왜냐하면 위의 예시도 Promotion이거든요!
어? 그러면 double값을 long에다가는 절대적으로 집어넣을 수 없는 건가요?
이 대답도 No 입니다.
집어넣을 수 있는 방법이 있는데 그 방법이 아직 설명드리지 않은 Casting입니다.
Casting
Casting은 강제 형 변환 이라는 의미를 가집니다.
말 그대로 자동 형 변환을 통해 변환되지 않는 것들을 강제적으로 변환을 시켜버린다는 의미입니다.
다른 표현으로는 위의 대소관계에서 값이 큰 타입에 저장되어 있는 값이 작은 타입에 집어 넣어질 때 변환되는 것을 말합니다.
다음 코드들을 봅시다.
package transform;
public class Casting {
public static void main(String[] args) {
double doubleVal = 660.52;
int intVal1 = 240;
int intVal2 = 128;
long longVal = (long)doubleVal;
short shortVal = (short)intVal1;
byte byteVal = (byte)intVal2;
System.out.println("longVal값: " + longVal);
System.out.println("shortVal값: " + shortVal);
System.out.println("byteVal값: " + byteVal);
}
}
위의 코드처럼 강제 형 변환을 할 때는 (자료형)의 형태를 넣어줌으로 써 형 변환을 해줄 수 있습니다.
longVal같은 경우는 doubleVal값이 660.52였지만 long이 정수형이기 때문에 소수점에 있는 값을 버리고 660이 나온 것을 확인하실 수 있습니다.
shortVal같은 경우는 int도 정수형이기 때문에 정상적으로 나온 것을 확인할 수 있습니다.
여기서 좀 특이한 것은 byteVal값 입니다.
분명히 intVal값은 128을 넣었지만 byteVal의 결과값은 -128이 나왔습니다.
왜 이렇게 나왔을까요?
정답은 오버플로우 때문입니다.
자료형에서 오버플로우라는 것은 넘쳐 흐른다라는 의미로 자료형의 값의 범위가 초과되었을 때 도달할 수 있는 값의 최솟값으로 다시 돌아가는 것을 의미합니다.
Byte의 값의 범위는 위의 그림 처럼 -128부터 127까지 입니다.
그리고 128이라는 값은 127 다음 값이죠?
그렇기에 128이라는 값이 들어왔을 때 127의 다음 값에 오버플로우가 겹쳐 결과적으로 -128이 나오게 된겁니다.
어? 그럼 -129를 byte에 넣게 되면 127이 나오게 되나요?
네, 맞습니다.
그리고 이거를 오버플로우의 반대인 언더플로우라고 부릅니다.
추가적으로 Casting에는 자료형들 뿐만 아니라 객체에도 똑같은 방식을 이용하여 적용시킬 수 있습니다.
이에 대한 내용도 추후에 관련 포스팅을 작성하게 된다면 적어보는 시간을 가져보겠습니다.
이상으로 형 변환에 대해 간단하게 알아보는 시간이었습니다.
읽어주셔서 감사합니다.
'Language > Java' 카테고리의 다른 글
[Java] 자바기초 - 생성자(Constructor) (0) | 2020.12.14 |
---|---|
[Java] 자바기초 - Wrapper Class (0) | 2020.12.13 |
[Java] 자바기초 - 자료형 (2) | 2020.12.10 |
[Java] 자바기초 - 입/출력 (0) | 2020.12.08 |
[Java] 자바기초 - IDE (0) | 2020.12.06 |
댓글