1. 형변환이란?
2. 자동 형변환
3. 강제 형변환
1. 형변환이란?
자바는 기본적으로 변수를 선언할 때 타입을 미리 지정해야하며,
형변환이란 이름 그대로 형을 변환시키는 것을 말합니다. 형은 자료형, 타입과 같은 말이라고 했고 결국 변수의 자료형을 다른 자료형으로 바뀌는 것을 이야기합니다. 프로그램에서 데이터를 다른 형식으로 변환하여 적절하게 사용할 수 있도록 하는 과정입니다. 형변환은 데이터 타입 간의 호환성을 보장하고, 계산 및 연산에서 데이터 손실을 방지하거나 최소화하는 데 중요합니다.
자바에서는 기본 자료형(타입)의 형변환이 필요할 때 두 가지 방법, 즉 묵시적 형변환(자동 형변환)과 명시적 형변환(강제 형변환)을 사용합니다.
2. 자동 형변환
자동 형(타입)변환은 프로그램 실행 중에 자동으로 타입이 변환되는 것을 말합니다. 작은 크기의 타입은 큰 크기를 가진 자료형에 저장될 때 자동 형변환이 일어나게 됩니다. 이 변환은 데이터 손실이 없기 때문에 자바 컴파일러가 자동으로 처리합니다. 예를 들면 종이컵에 담긴 물을 양동이에 담는것을 생각하면 됩니다. 작은 종입컴에 담긴 물은 큰 양동이에 담으면 아무 문제 없이 담기겠죠?
int intValue = 100;
long longValue = intValue; // 자동 형변환 (int -> long)
int(정수) 타입의 intValue 변수에 정수 100을 대입하고
long(정수) 타입의 longValue 변수에 int 타입의 변수 intValue의 값을 대입합니다. 이때 타입은 다르지만 자동형변환이 일어나게 됩니다.
큰 크기 타입 = 작은 크기 타입
기본자료형의 크기 순으로 나열하면 아래와 같습니다.
byte < short < int < long < float < double
작은 자료형 <------------------> 큰 자료형
이번엔 반대로 작은 자료형 변수에 큰 범위의 값을 대입해보자.
long longVal = 100;
int intVal = longVal;
위 코드는 에러가 발생한다. longVal 변수를 대입하는 부분에서 에러가 나고 빨간색으로 표기가 될텐데 마우스를 갖다 대보면 "Type mismatch: cannot convert from long to int" 라는 메시지가 보일 것이다.
직역해 보자면, 타입이 맞지 않는다: long타입을 int 타입으로 변환(convert)할 수 없다고 한다. 자바는 기본적으로 해당 변수의 타입의 값만 대입할 수 있으면 다른 타입은 담을 수 없다. 자동 형변환이 일어나면 가능하지만 위 코드는 자동형변환이 일어나지 않으므로 에러가 발생한 것이다.
3. 강제형변환
자동 형변환에서 비유했던 종이컵과 양동이의 비유를 다시 생각해보면 종이컵에 들어있는 물의 양이 양동이보다 작기 때문에 양동이에 충분히 담을 수 있었는데, 반대로 양동이에 들어 있는 물은 작은 종이컵에 넣을 수가 없습니다. 만약 억지로 종이컵으로 옮겨 담으려면 넘치는 물을 다 버리고, 종이컵에 들어갈 만큼만 담을 수 밖에 없게 되겠죠, 이것이 바로 강제 형변환입니다. 강제 형변환은 값을 대입하기 전에 괄호로 변환하고자 하는 대상의 타입 이름을 넣어줘야 합니다.
작은 크기 타입 = (작은 크기 자료형) 큰 크기 타입
양동이에 가득 들어 있던 물을 종이컵에 억지로 물을 담게 되면 종이컵 크기 이상의 물은 모두 버려지게 됩니다. 이때 값의 손실이 발생하는데, 아래 예제를 보면 쉽게 이해가 될것입니다.
double doubleValue = 9.99;
int intValue = (int) doubleValue; // 강제 형변환 (double -> int)
위 예제에서 double 자료형을 int로 형변환할 때, 소수점 이하의 값이 버려집니다. 따라서 doubleValue는 9.99였지만, intValue는 9가 됩니다. 헷갈리지 말아야할 점은 반올림이 아니라 버려진다는 것입니다.
다른 예제를 살펴보겠습니다.
// 강제형변환 예시
double score = 100; // double 자료형
int score2 = (int)score; // 강제형변환
System.out.println(score2); // 값의 손실 발생하지 않음
실행해보면 100.0이 출력되는데, score라는 double 타입의 변수에 100이라는 값이 담겨 있습니다. 타입은 double이지만, 값이 int 자료형의 범위에도 포함되는 값입니다. 따라서 int 타입의 score2 변수에 강제 형변환을 통해 대입해도 손실이 발생하지 않습니다. 100과 100.0은 출력형태만 달라졌을 뿐입니다. 다시 종이컵 예를 들면, 양동이에 종이컵 크기만큼의 물만 들어있었다면, 종이컵에 옮겨 담아도 버리는 물 없이 담을 수 있게 되는 것이죠.