타입 캐스팅
자바에서 한 타입의 값이나 참조를 다른 타입으로 변환하는 것으로, 상위 타입으로 변환하는 업캐스팅과 하위 타입으로 변환하는 다운캐스팅으로 나뉩니다.
업캐스팅과 다운캐스팅
| 구분 | 설명 | 안전성 |
|---|---|---|
| 업캐스팅 | 하위 타입 → 상위 타입 | 컴파일러가 보장, 항상 안전 |
| 다운캐스팅 | 상위 타입 → 하위 타입 | 명시적 캐스팅 필요, 실패 시 예외 발생 |
Object obj = "hello"; // 업캐스팅 - 자동으로 이루어짐
String str = (String) obj; // 다운캐스팅 - 명시적 캐스팅 필요
ClassCastException
다운캐스팅 대상이 실제로 해당 타입이 아니면 런타임에 ClassCastException이 발생합니다.
Object intValue = 10;
String str1 = (String) intValue; // ClassCastException
Object nullValue = null;
String str2 = (String) nullValue; // null (예외 발생 X)
str2.concat("maeilmail"); // NullPointerException
null은 캐스팅 시 예외 없이 그대로 통과되지만, 이후 메서드를 호출하는 시점에 NullPointerException이 발생할 수 있습니다.
instanceof로 안전하게 캐스팅하기
캐스팅 전에 instanceof로 타입을 먼저 확인하면 ClassCastException을 방지할 수 있습니다.
Object intValue = 10;
if (intValue instanceof String str) {
System.out.println(str);
} else {
// 캐스팅 대상이 아닐 때의 처리
}
String.valueOf()와의 차이
(String) value 캐스팅과 String.valueOf(value)는 둘 다 String 타입을 얻는다는 점은 같지만 동작 방식이 다릅니다.
| 항목 | (String) value | String.valueOf(value) |
|---|---|---|
| 동작 | 타입 검사만 수행, 실제 변환 없음 | 내부적으로 toString()을 호출해 값을 변환 |
| value가 String이 아닐 때 | ClassCastException | value.toString() 결과를 반환 |
| value가 null일 때 | null 반환 (이후 NPE 위험) | "null" 문자열 반환 |
Object intValue = 10;
String str1 = String.valueOf(intValue); // "10"
Object nullValue = null;
String str2 = String.valueOf(nullValue); // "null"
str2.concat("maeilmail"); // "nullmaeilmail"
캐스팅에서 발생하는 예외는 런타임에서만 드러나기 때문에, 타입이 확실하지 않다면 String.valueOf()가 더 안전합니다. 다만 String.valueOf(null)이 "null" 문자열을 반환하는 점은 JSON 변환이나 DB 저장 시 실제 null과 혼동될 수 있어 주의가 필요합니다.
핵심 정리
타입 캐스팅은 컴파일러가 보장하는 업캐스팅과 달리, 다운캐스팅은 실패 시 ClassCastException이 발생할 수 있는 위험한 연산입니다. 안전하게 캐스팅하려면 instanceof로 사전 검증하거나, 문자열 변환이 목적이라면 String.valueOf()를 사용하는 것이 좋습니다.
→ 자바에서 Object 타입인 value를 String으로 타입 캐스팅하는 것과 String.valueOf()를 사용하는 것의 차이점은 무엇인가요?