자바에서 자료형은 크게 두 분류로 나눌 수 있다.
- 기본형 타입(Primitive type)
- int, float, char 같은 기본형 자료형이라 할 수 있다.
- 참조형 타입(Reference type)
- 기본형 타입을 제외한 모든 타입이라 할 수 있다.
- 일반적으로 클래스, 인터페이스, 열거형(enum), 배열 모두 포함한다.
그리고 형변환은 다음과 같은 2가지 유형에서 이루어진다.
// 암시적 형변환(확대)
int num1 = 10;
double num2 = num1;
System.out.println("num2: " + num2);
// 명시적 형변환(축소)
double num3 = 10.5;
int num4 = (int) num3;
System.out.println("num4: " + num4);
기본형 타입들의 타입캐스팅은 모두 문제없이 서로 형변환이 가능하다. 다만 자료형의 확대 개념에 있어서 형변환은 암시적 캐스팅이 가능하나 그 반대의 경우 캐스트 연산자를 사용하여 명시적 형변환을 해주어야 한다.
사실 참조형 타입들은 기본적으로 타입캐스팅이 불가능하다. 여러 자료형이 묶어져 있는 참조형 타입이 서로 변환될 수 있다는 것 부터 어불성설. 하지만 참조형 타입이 서로 상속관계일 경우 형변환이 가능하다. 이는 두 가지 경우로 나눌 수 있는데
- 부모타입 변수에 자식타입 객체를 할당.
- 업캐스팅(Up-Casting)
- 암시적 형변환 가능.
- 자식타입 변수에 부모타입 객체를 할당.
- 다운캐스팅(Down-Casting)
- 명시적 형변환 필수.
다음과 같이 정리 할 수 있고 예제를 살펴보면
// 'Animal'클래스는 'Dog'클래스의 부모 클래스이고 'Dog'클래스는 'Animal'클래스를 상속한다고 가정. 즉 서로 상속관계 일때
// 업캐스팅 (암시적)
Animal animal = new Dog();
// 다운캐스팅 (명시적)
Dog dog = (Dog) new Animal();
예제를 보면 부모타입변수에 자식객체를 할당 할 때, 즉, 업캐스팅일 경우 암시적 형변환이 가능하며 캐스팅 연산자를 제외할 수 있다. 하지만 그 반대의 경우, 즉, 부모타입객체를 자식변수에 할당 할 때 반드시 캐스팅 연산자로 명시적 형변환을 해줘야 하며 이를 다운캐스팅이라고 한다.
다운캐스팅은 보통 런타임오류가 나올 가능성이 높아 현업에서 지양하는 편이며 ClassCastException이 발생할 수 있다는 점에서 항상 유의하여야 한다.