📚 타입변환


특정 자료형 범위 내에서는 자료형을 변환할 수 있는데 이를 타입변환이라고 한다. 타입변환도 상속관계가 없을 때는 특정 변환 함수나 클래스를 만들어 변환 처리해야 한다.


📔 타입 체크 및 변환 연산자

자료형에 대한 타입을 연산자로 확인한 후에는 타입이 자동으로 변환한다. 이를 스마트 캐스팅이라고 한다.

  • 타입을 확인하는 연산자(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