https://kotlinlang.org/docs/inline-classes.html
value
키워드JvmInline
어노테이션@JvmInline
value class Password(private val s: String)
@JvmInline
value class Person(private val fullName: String) {
init {
require(fullName.isNotEmpty())
}
constructor(firstName: String, lastName: String) : this("$firstName $lastName") {
require(lastName.isNotBlank())
}
// 인라인 클래스의 프로퍼티 getter 및 함수는 static 함수로 호출된다.
val length: Int
get() = fullName.length
fun greet() {
println("Hello, $fullName")
}
}
lateinit
불가@JvmInline
value class Name(val s: String) : Printable {
override fun prettyPrint(): String = "Let's $s!"
}
final
클래스이다.int
와 Integer
처럼)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: Foo 자체를 사용
asGeneric(f) // boxed: T 타입의 제네릭으로 사용
asInterface(f) // boxed: 인터페이스 I 타입으로 사용
asNullable(f) // boxed: nullable 타입으로 사용, Foo와 차이는?
// 아래 f는 id 함수의 매개변수에 패싱될 땐 래퍼 타입 이지만
// 함수 내부에서 리턴될 땐 원시 타입으로 unboxing된다.
val c = id(f)
}
a === b
Any?
또는 타입 파라미터의 상한에 매핑한다.@JvmInline
value class UserId<T>(val value: T)
fun compute(s: UserId<String>) // fun compute-<hashcode>(s: Any?)
@JvmInline
value class UInt(val x: Int)
// JVM에서 'public final void compute(int x)'로 표현된다
fun compute(x: Int) { }
// 아래도 마찬가지로 JVM에서 'public final void compute(int x)'로 표현된다.
fun compute(x: UInt) { }
compute-<해시코드>(int x)
@JvmInline
value class UInt(val x: Int)
fun compute(x: Int) { }
@JvmName("computeUInt") // 맹글링 비활성화
fun compute(x: UInt) { }
interface MyInterface {
fun bar()
fun foo() = "foo"
}
@JvmInline
value class MyInterfaceWrapper(
val myInterface: MyInterface
) : MyInterface by myInterface
fun main() {
val myInterfaceImpl = Object : MyInterface {
override fun bar() { }
}
val my = MyInterfaceWrapper(myInterfaceImpl)
println(my.foo()) // prints "foo"
}