[Kotlin] 타입변환
📚 타입변환
특정 자료형 범위 내에서는 자료형을 변환할 수 있는데 이를 타입변환이라고 한다. 타입변환도 상속관계가 없을 때는 특정 변환 함수나 클래스를 만들어 변환 처리해야 한다.
📔 타입 체크 및 변환 연산자
자료형에 대한 타입을 연산자로 확인한 후에는 타입이 자동으로 변환한다. 이를 스마트 캐스팅
이라고 한다.
- 타입을 확인하는 연산자(is/!is): 상속관계에 해당하는 타입일 때만 is, !is 로 점검할 수 있다
- 타입을 변환하는 연산자(as/as?): 타입을 변환할 때도 상속관계 내에서 가능하고 불가능할 경우 as?로 처리하면 null이 반환된다
📔 타입 체크
fun checkDataType(value: Any) {
if(value is String) {
println("$value 는 문자열")
}
if(value !is String) {
println("$value 는 문자열이 아님")
}
if(value is Int) {
println("$value 는 정수")
}
if(value !is Int) {
println("$value 는 정수가 아님")
}
}
checkDataType(100)
checkDataType("문자열")
100 는 문자열이 아님
100 는 정수
문자열 는 문자열
문자열 는 정수가 아님
📔 다양한 조건에 대한 타입 체크
when을 사용하여 보다 다양한 자료형을 체크할 수 있다.
val num: Any = 256
if(num is Int) {
println(num)
println(num.javaClass.kotlin)
} else {
println("not Int")
}
val x: Any = 100
when(x) {
is Int -> println(x + 1)
is String -> println(x.length + 1)
else -> print("no")
}
256
class kotlin.Int
101
📔 상속관계를 벗어난 타입 체크
상속관계를 벗어난 경우는 연산자로 타입변환을 할 수 없다. 별도의 메서드 등을 작성해서 타입을 변환한다.
val a: Number = 100
// println(a is String) 숫자와 문자열은 상속 관계가 아니므로 처리할 수 없다
// println(a !is String)
println(a !is Long) // 숫자 자료형을 상속한 경우 가능
val b: Any = 100 // 최상위 클래스
println(b is String) // 숫자와 문자열은 Any와 상속관계
println(b !is String)
println(b !is Long)
true
false
true
true
📔 스마트 캐스팅이 불가능한 경우
스마트 캐스팅은 명확한 값이 있어야 자료형을 확인할 수 있다. 명확한 값이 처리되지 않는 경우는 스마트 캐스팅이 불가능하다.
class AAA {
lateinit var ainit: Any // 초기화 연기
val o: Any
get() = ""
}
val a = AAA()
if (a.o is String) {
// println(a.o.length) 스마트 캐스트 처리 불가
}
a.ainit = ""
if (a.ainit is String) {
// println(a.ainit.length) 스마트 캐스트 처리 불가
}
아래의 경우에서는 스마트 캐스팅이 가능하다.
class BBB {
val lazyB by lazy {300} // 지연 초기화
fun lazyFunc() {
if (lazyB is Int) {
println(lazyB * 2)
}
}
}
val b = BBB()
b.lazyFunc()
val Any.ccc: Int
get() = 100
println(("문자열").ccc is Int)
600
true
📔 숫자 자료형 변환
val a: Long = 34
val b: Int = a.toInt() // Long을 Int로 강제 형 변환
val str: String = "123"
val c = str.toInt() // 정수형으로 변환
println("$b $c")
34 123
📔 명식적 자료형 변환
- 널러블 자료형이 일반 자료형보다 상위이므로
as
를 사용해서 널러블 자료형을 일반 자료형으로 변환한다 - 널러블 자료형에 널이 들어올 수 있으므로 자료형 변환에
as?
를 사용한다
var x: String = "100"
var y: String? = "3000"
x = y as String
println(x)
var a: Any? = "100"
var b: String? = "3000"
b = a as String
println(b)
val c = a as? String ?: 0
println(c)
var e: String = "100"
var f: String? = null
val g = f as? String ?: 0
println(g)
3000
100
100
0