Kotlin 공식 문서 살펴보기 (6) - 타입 확인과 캐스트
28 Jan 2022is & !is 연산자
- 객체가 주어진 타입과 맞는지 여부를 확인하는 런타임 검사
if (obj is String) {
print(obj.length)
}
if (obj !is String) {
print("not a stirng")
} else {
print(obj.length)
}
스마트 캐스트
- 대부분의 경우 명확한 캐스트 연산자를 사용할 필요가 없음
- 컴파일러가
is
확인을 트래킹하고 값을 변경할 수 없는 객체에 명시적 캐스트를 하고 필요할 경우 자동으로 안전한 캐스트를 함
fun demo(x: Any) {
if (x is String) {
print(x.length) // x는 자동으로 문자열로 캐스팅됨
}
}
- 컴파일러는 부정 확인이 return으로 끝날 경우, 캐스트가 안전한 것을 알 수 있음
if (x !is String) return
print(x.length) // x는 자동으로 문자열로 캐스팅됨
- 또는 캐스팅이
&&
,||
의 오른쪽에 있고 타입 확인이 왼쪽에 있을 때도 동일
// x는 ||의 오른편에서 자동으로 문자열로 캐스팅됨
if (x !is Strijng || x.length == 0) return
// x는 &&의 오른편에ㅓ 자동으로 문자열로 캐스팅됨
if (x is String && x.length > 0) {
print(x.length)
}
- 스마트 캐스트는
when
표현식과while
루프에서도 동작
when (x) {
is Int -> print(x + 1)
is String -> print(x.length + 1)
is IntArray -> print(x.sum())
}
- 스마트 캐스트는 변수가 확인과 사용법이 바뀌지 않을 것을 컴파일러가 보증할 때만 동작
안전하지 않은 캐스트 연산자
- 보통 캐스팅 할 수 없으면 예외가 발생하며 이를 안전하지 않다(unsafe)고 함
- 안전하지 않은 캐스트는
as
로 수행
val x: String = y as String
- null은 문자열로 캐스트될 수 없고 만약 위에서 y가 null이면 예외 발생
- null값을 위해 위의 예제를 바꾸려면 캐스트 오른쪽에 null 타입을 추가
val x: String? = y as String?
안전한 nullable 캐스트 연산자
- 예외를 방지하기 위해 실패할 때 null을 반환하는 안전한 캐스트 오퍼레이터인
as?
를 사용
val x: String? = y as? String
as?
의 오른쪽이 nullable하지 않은 문자열이어도 캐스트의 결과는 nullable 함
타입 삭제와 제네릭 타입 확인
- 코틀린은 컴파일 시간에 제네릭 관련 작업에 타입 안정성 보장
- 런타임에서는 제네릭 타입의 인스턴스는 실제 타입 인자에 대한 정보를 가지고 있지 않음
- 런타임에서는 타입 삭제 때문에 컴파일러는 제네릭 타입은
is
확인을 금지 *
이용한 인스턴스 확인은 가능
if (something is List<*>) {
something.forEach( println(it) )
}
- 컴파일 시간에 정적 인스턴스 타입 검사가 이루어진 경우에는
is
확인과 제네릭이 아닌 부분을 포함하는 캐스트 가능
fun handleStrings(list: List<String>) {
if (list is ArrayList) {
// list 는 ArrayList<String> 으로 스마트 캐스트 됨
}
}
확인되지 않은 캐스트
- 확인되지 않은 캐스트를 방지할 수 있는 방법
- 추상화
reified
타입 파라미터@Superclass("UNCHECKED_CAST")
어노테이션