이 장은 Kotlin Serialization 가이드의 두 번째 장입니다. 모든 원시(primitive) 타입 및 문자열 외에도 표준 컬렉션을 비롯해 Kotlin 표준 라이브러리의 일부 클래스에 대한 직렬화가 Kotlin 직렬화 플러그인에 내장되어 있습니다. 이번 장에서는 이러한 빌트인 클래스에 대한 자세한 내용을 설명합니다.
원시(primitive) 타입
Kotlin 직렬화는 다음의 10가지의 원시 타입을 가지고 있습니다. Boolean, Byte, Short, Int, Long, Float, Double, Char, String, 그리고 열거형(enum)입니다. Kotlin 직렬화에서의 다른 타입들은 이러한 원시값으로 구성된 복합 형태입니다.
숫자
Kotlin 직렬화는 모든 타입의 정수 및 부동 소수점(floating-point) 숫자를 직렬화할 수 있습니다.
// https://github.com/Kotlin/kotlinx.serialization/blob/master/guide/example/example-builtin-01.kt
package example.exampleBuiltin01
import kotlinx.serialization.*
import kotlinx.serialization.json.*
import kotlin.math.*
//sampleStart
@Serializable
class Data(
val answer: Int,
val pi: Double
)
fun main() {
val data = Data(42, PI)
println(Json.encodeToString(data))
}
//sampleEnd
결과는 다음과 같습니다.
{"answer":42,"pi":3.141592653589793}
긴 숫자
긴 정수 역시 직렬화할 수 있습니다.
// https://github.com/Kotlin/kotlinx.serialization/blob/master/guide/example/example-builtin-02.kt
package example.exampleBuiltin02
import kotlinx.serialization.*
import kotlinx.serialization.json.*
//sampleStart
@Serializable
class Data(val signature: Long)
fun main() {
val data = Data(0x1CAFE2FEED0BABE0)
println(Json.encodeToString(data))
}
//sampleEnd
기본적으로 JSON에서 숫자로 직렬화됩니다.
{"signature":2067120338512882656}
긴 숫자를 문자열로 변환
이전 예제의 JSON 출력은 Kotlin/JS에서 실행되는 Kotlin 직렬화에 의해 정상적으로 디코딩됩니다. 하지만 네이티브 JavaScript 메서드를 통해 이 JSON을 파싱하면 다음과 같이 일부 값이 잘린 결과가 나타납니다.
Kotlin Long의 전체 범위는 JavaScript 숫자 범위보다 크기 때문에 JavaScript 에서 정밀도(precision)가 손실됩니다. 이런 경우에 일반적인 해결 방법은 긴 숫자를 전체 정밀도를 유지하는 문자열 유형으로 표현하는 것입니다. 이 방법은 해당 Long 프로퍼티에 @Serializable 어노테이션의 LongAsStringSerializer 값을 지정하는 방식으로 사용 가능합니다.
// https://github.com/Kotlin/kotlinx.serialization/blob/master/guide/example/example-builtin-03.kt
package example.exampleBuiltin03
import kotlinx.serialization.*
import kotlinx.serialization.json.*
import kotlinx.serialization.builtins.*
//sampleStart
@Serializable
class Data(
@Serializable(with=LongAsStringSerializer::class)
val signature: Long
)
fun main() {
val data = Data(0x1CAFE2FEED0BABE0)
println(Json.encodeToString(data))
}
//sampleEnd
다음 예제에서 볼 수 있듯이 모든 열거형 클래스는 @Serializable을 표시하지 않고도 바로 직렬화할 수 있습니다.
All enum classes are serializable out of the box without having to mark them @Serializable, as the following example shows.
package example.exampleBuiltin04
import kotlinx.serialization.*
import kotlinx.serialization.json.*
//sampleStart
// 열거형 클래스는 @Serializable 어노테이션이 필요하지 않음
enum class Status { SUPPORTED }
@Serializable
class Project(val name: String, val status: Status)
fun main() {
val data = Project("kotlinx.serialization", Status.SUPPORTED)
println(Json.encodeToString(data))
}
//sampleEnd
Kotlin/JS와 Kotlin/Native 에서는 enum 클래스를 root 객체로 사용(예를 들어, encodeToString<Status>(Status.SUPPORTED)와 같이 사용)하려면 @Serializable 어노테이션이 필요합니다.
열거형 항목의 serial 이름
열거형 항목의 serial 이름은 Serial 필드명항목에서 프로퍼티에 대해 설정한 것과 마찬가지로 SerialName 어노테이션을 통해 사용자 지정할 수 있습니다. 단, 이 경우 전체 열거형 클래스에 @Serializable 어노테이션을 표시해야 합니다.
package example.exampleBuiltin05
import kotlinx.serialization.*
import kotlinx.serialization.json.*
//sampleStart
@Serializable // @SerialName 때문에 필수로 설정해야 함
enum class Status { @SerialName("maintained") SUPPORTED }
@Serializable
class Project(val name: String, val status: Status)
fun main() {
val data = Project("kotlinx.serialization", Status.SUPPORTED)
println(Json.encodeToString(data))
}
//sampleEnd
결과를 보면 JSON 결과에 @SerialName에 지정된 값이 사용된 것을 확인할 수 있습니다.