Hanbit the Developer
Kotlin Documentation | Inline classes 본문
Category: Concepts - Classes and objects
문서 링크: https://kotlinlang.org/docs/inline-classes.html
Backgrounds
class Password(private val s: String)
- 위처럼 데이터가 한 개가 필요하지만 클래스로 wrap해야 하는 경우가 있다.
- 위처럼 하면 힙에 인스턴스를 추가해야 하기 때문에 오버헤드가 심하다.(primitive type일 경우에는 특히 더 심하다.)
Usage
value class Password(private val s: String)
// To declare an inline class for the JVM backend
@JvmInline
value class Password(private val s: String)
Attributes
- single property
- immutable(val property만 가능)
- Inheritance, delegation(by) 가능
vs data class
automatically generates:
data class | equals(), toString(), hashCode(), copy(), componentN() |
inline class | equals(), toString(), hashCode() |
Members
@JvmInline
value class Name(val s: String) {
init {
require(s.length > 0) { }
}
val length: Int
get() = s.length
fun greet() {
println("Hello, $s")
}
}
fun main() {
val name = Name("Kotlin")
name.greet() // method `greet` is called as a static method
println(name.length) // property getter is called as a static method
}
Representation
interface I
@JvmInline
value class Foo(val i: Int) : I
fun asInline(f: Foo) {}
fun <T> asGeneric(x: T) {}
fun asInterface(i: I) {}
fun asNullable(i: Foo?) {}
fun <T> id(x: T): T = x
fun main() {
val f = Foo(42)
asInline(f) // unboxed: used as Foo itself
asGeneric(f) // boxed: used as generic type T
asInterface(f) // boxed: used as type I
asNullable(f) // boxed: used as Foo?, which is different from Foo
// below, 'f' first is boxed (while being passed to 'id') and then unboxed (when returned from 'id')
// In the end, 'c' contains unboxed representation (just '42'), as 'f'
val c = id(f)
}
vs typealias
typealias NameTypeAlias = String
@JvmInline
value class NameInlineClass(val s: String)
fun acceptString(s: String) {}
fun acceptNameTypeAlias(n: NameTypeAlias) {}
fun acceptNameInlineClass(p: NameInlineClass) {}
fun main() {
val nameAlias: NameTypeAlias = ""
val nameInlineClass: NameInlineClass = NameInlineClass("")
val string: String = ""
acceptString(nameAlias) // OK: pass alias instead of underlying type
acceptString(nameInlineClass) // Not OK: can't pass inline class instead of underlying type
// And vice versa:
acceptNameTypeAlias(string) // OK: pass underlying type instead of alias
acceptNameInlineClass(string) // Not OK: can't pass underlying type instead of inline class
}
References
https://velog.io/@dhwlddjgmanf/Kotlin-1.5에-추가된-value-class에-대해-알아보자
'Kotlin' 카테고리의 다른 글
Kotlin Documentation | Delegation (0) | 2023.05.23 |
---|---|
Kotlin Documentation | Object expressions and declarations (0) | 2023.05.23 |
Kotlin Documentation | Enum classes (0) | 2023.05.23 |
Kotlin Documentation | Nested and inner classes (0) | 2023.05.23 |
Kotlin Documentation | Generics: in, out, where (0) | 2023.05.23 |