형 변환은 프로그래밍에서 데이터를 다룰 때 필수적인 기술 중 하나로 데이터의 타입을 변환하는 프로세스를 의미한다. 데이터를 다루다 보면 서로 다른 데이터 형식 간의 변환이 필요한 순간이 자주 발생한다. 이럴 때 형 변환을 통하여 데이터 형식을 통일시키거나 원하는 형식으로 변경할 수 있다. 자바에서는 데이터 타입 간의 형 변환이 필요한 경우가 많으며, 묵시적 형 변환과 명시적 형 변환 두 가지 유형으로 나눌 수 있다.
묵시적 형 변환은 자동으로 발생하는 형 변환이며, 자바에서는 데이터의 손실 없이 작은 데이터 타입에서 큰 데이터 타입으로 형 변환된다. 정수 데이터를 실수로 변환하거나 작은 정수 데이터 타입을 큰 정수 데이터 타입으로 변환하는 등 작은 데이터 타입의 값을 큰 데이터 타입의 변수에 대입하는 경우에 발생한다.
예를 들어, int를 double로 대입하거나 short를 int로 대입하는 경우이다.
int myInt = 42;
double myDouble = myInt; // 묵시적 형변환
위의 코드에서 myInt는 int 타입이고 myDouble은 double 타입이다. myInt의 값을 myDouble에 대입할 때 묵시적으로 int에서 double로 형 변환이 일어나는데, int는 double보다 작은 데이터 타입이므로 int 값을 double로 할당하면 데이터 손실 없이 int 값이 double로 자동 형 변환된다.

자바에서는 데이터 타입의 표현 범위에 따라 이미지와 같은 방향으로 묵시적 형 변환이 이루어진다.
이미지를 보면 short와 char의 크기가 같은데 묵시적 형 변환이 이루어지지 않거나 long이 float보다 크기는 크지만 묵시적인 형 변환이 이루어지지 않는 것을 알 수 있다.
이러한 이유는 데이터 표현 방식의 차이 때문이다.
short와 char은 모두 2 바이트의 크기를 갖지만, short는 부호 있는(signedt) 정수 데이터 타입으로 음수와 양수 값을 표현(-32,768 ~ 32,767) 할 수 있고, char는 부호 없는(unsigned) 정수 데이터 타입으로 양의 정수를 표현(0 ~ 65535) 하는데 사용된다. 따라서 short와 char는 서로 데이터 표현 범위 범위가 달라서 둘 중 어느 쪽으로의 형 변환은 값 손실이 발생할 수 있으므로 묵시적으로 형 변환이 수행될 수 없다.
또한, 8 바이트인long과 4 바이트인float 중에서 크기는 long이 더 크지만 데이터 표현 범위는 float이 더 크다. 게다, long은 정수 데이터 타입이고 float는 부동 소수점 데이터 타입이다. 부동 소수점은 소수점 이하 값을 저장할 수 있고, 정수는 소수점 이하 값을 저장하지 않는데, 정수 데이터 타입인 long에서 부동 소수점 데이터 타입인 float로의 묵시적 형 변환은 데이터 손실이 발생할 수 있기 때문에 자동으로 수행되지 않는다.
명시적 형 변환은 개발자가 직접 형변환을 수행하는 것으로, 큰 데이터 타입을 작은 데이터 타입으로 변환할 때 사용된다. 이 경우, 데이터 손실이 발생할 수 있으므로 주의해야 한다. 명시적 형 변환은 괄호 안에 변환하려는 타입을 명시해주어야 한다.
예를 들어, double에서 int로 형변환하는 경우가 있다. double은 int보다 큰 데이터 타입이므로 명시적 형변환을 사용하여 double 값을 int로 변환할 수 있다.
double myDouble = 3.14;
int myInt = (int) myDouble; // 명시적 형 변환
위의 코드에서 myDouble은 double 타입이고 myInt는 int 타입이다. myDouble의 값을 int로 형변환하려면 (int)로 명시적으로 표현한다. 이때 데이터의 손실이 발생하므로 주의가 필요하다.
(double은 실수를 표현할 수 있는 데이터 타입으로 소수점 아래 값을 가질 수 있지만, int는 정수 데이터 타입으로 소수점 이하의 값을 저장할 수 없다. 따라서 3.14와 같은 실수 값은 int로 변환할 때 소수점 이하 데이터가 손실되고 3으로 줄어들게 된다.)
자바에서 형 변환을 다룰 때 몇 가지 주의할 점이 있다.
데이터 손실
큰 데이터 타입에서 작은 데이터 타입으로 형 변환 시 데이터 손실이 발생할 수 있으므로 주의해야 한다.
무효한 형 변환
서로 호환되지 않는 데이터 타입 간의 형 변환은 무효하며 컴파일 오류를 일으킨다.
범위 초과
정수 데이터 타입을 다른 정수 데이터 타입으로 변환할 때 범위 초과에 주의해야 한다.
부호 비트 손실
부호 있는 데이터 타입을 부호 없는 데이터 타입으로 변환할 때 부호 비트 손실이 발생할 수 있다.
int intNumber = 42;
double doubleNumber = (double) intNumber;
String strNumber = "123";
int intNumber = Integer.parseInt(strNumber);
int[] intArray = {1, 2, 3};
double[] doubleArray = new double[intArray.length];
for (int i = 0; i < intArray.length; i++) {
doubleArray[i] = (double) intArray[i];
}
// Date를 문자열로 변환
Date currentDate = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
String dateString = dateFormat.format(currentDate);
// 문자열을 Date로 변환
String dateStr = "2023-09-10";
Date parsedDate = dateFormat.parse(dateStr);
int flags = 5; // 이진 플래그: 101
boolean isFlagSet = (flags & 4) != 0; // 비트 2(4)가 설정되어 있는지 확인
class Animal { }
class Dog extends Animal { }
Animal animal = new Dog(); // Dog를 Animal로 형 변환
interface Shape { void draw(); }
class Circle implements Shape { /* 구현 생략 */ }
Shape shape = new Circle(); // Circle을 Shape로 형 변환
List<Shape> shapes = new ArrayList<>();
shapes.add(new Circle());
shapes.add(new Rectangle());
for (Shape shape : shapes) {
shape.draw();
}
형 변환은 다양한 상황에서 프로그램의 유연성과 확장성을 높이는 데 도움이 되며, 데이터를 필요한 형식으로 변환하거나 다양한 객체를 처리하는 데 중요한 역할을 한다. 하지만 데이터의 유효성을 검사하고 적절한 예외 처리를 수행하여 형 변환 오류를 방지하는 것도 중요하다.