티스토리 뷰

Programming/Kotlin

Kotlin Reflection

Albothyl 2022. 4. 30. 14:53

add dependency

// 명령줄 컴파일러 또는 Ant를 사용하는 IntelliJ IDEA 프로젝트)에서는 기본적으로 추가됩니다. 
// 명령줄 컴파일러 및 Ant에서 -no-reflect컴파일러 옵션을 사용 kotlin-reflect.jar하여 
// 클래스 경로에서 제외할 수 있습니다.
dependencies {
    implementation "org.jetbrains.kotlin:kotlin-reflect:1.6.21"
}

Class references

- The most basic reflection feature is getting the runtime reference to a Kotlin class. To obtain the reference to a statically known Kotlin class, you can use the class literal syntax:

- Class에서 직접 참조를 얻는다.

val c = MyClass::class

주의

- On JVM: a Kotlin class reference is not the same as a Java class reference. To obtain a Java class reference, use the .java property on a KClass instance.


Bound class references

- You can get the reference to the class of a specific object with the same ::class syntax by using the object as a receiver:

- binding된 객체에서 Class 참조를 얻는다.

val widget: Widget = ...
assert(widget is GoodWidget) { "Bad widget: ${widget::class.qualifiedName}" }

Callable references

fun main() {
	fun isOdd(x: Int) = x % 2 != 0
    
    val numbers = listOf(1, 2, 3)
    
    println(numbers.filter(it -> isOdd(it))) // 직접적인 호출
    println(numbers.filter(::isOdd)) //method references를 이용한 호출
}

// overloading
fun main() {
    fun isOdd(x: Int) = x % 2 != 0
    fun isOdd(s: String) = s == "brillig" || s == "slithy" || s == "tove"

    val numbers = listOf(1, 2, 3)
    println(numbers.filter(::isOdd)) // refers to isOdd(x: Int)
    
    // 명시적으로 지정된 유형의 변수에 method references를 저장하여 필요한 컨텍스트를 제공할 수 있습니다.
    val predicate: (String) -> Boolean = ::isOdd   // refers to isOdd(x: String)
}

//More Example
fun <A, B, C> compose(f: (B) -> C, g: (A) -> B): (A) -> C {
    return { x -> f(g(x)) }
}

fun isOdd(x: Int) = x % 2 != 0

fun main() {
    fun length(s: String) = s.length

    val oddLength = compose(::isOdd, ::length)
    val strings = listOf("a", "ab", "abc")

    println(strings.filter(oddLength))
}

Property references

val x = 1

fun main() {
    println(::x.get())
    println(::x.name)
}

----------------------------
// A property reference can be used where a function with a single generic parameter is expected:
fun main() {
    val strs = listOf("a", "bc", "def")
    println(strs.map(String::length))
}

-----------------------------

fun main() {
    class A(val p: Int)
    val prop = A::p
    println(prop.get(A(1)))
}

val String.lastChar: Char
    get() = this[length - 1]

fun main() {
    println(String::lastChar.get("abc"))
}
 

Interoperability with Java reflection

import kotlin.reflect.jvm.*

class A(val p: Int)

// to find a backing field or a Java method that serves as a getter for a Kotlin property, you can write something like this:
fun main() {
    println(A::p.javaGetter) // prints "public final int A.getP()"
    println(A::p.javaField)  // prints "private final int A.p"
}

----------------------------
// To get the Kotlin class that corresponds to a Java class, use the .kotlin extension property:
fun getKClass(o: Any): KClass<Any> = o.javaClass.kotlin

Constructor references

class Foo

fun function(factory: () -> Foo) {
    val x: Foo = factory()
}

// ::ClassName 으로 Constructor references를 얻을 수 있다.
function(::Foo)

Bound function and property references

fun main() {
    val numberRegex = "\\d+".toRegex()
    println(numberRegex.matches("29"))

    val isNumber = numberRegex::matches
    println(isNumber("29"))
}

----------------------------

fun main() {
    val numberRegex = "\\d+".toRegex()
    val strings = listOf("abc", "124", "a70")
    println(strings.filter(numberRegex::matches))
}

----------------------------

val isNumber: (CharSequence) -> Boolean = numberRegex::matches

val matches: (Regex, CharSequence) -> Boolean = Regex::matches

----------------------------

fun main() {
    val prop = "abc"::length
    println(prop.get())
}

Bound constructor references

- A bound callable reference to a constructor of an inner class can be obtained by providing an instance of the outer class:

class Outer {
    inner class Inner
}

val o = Outer()
val boundInnerCtor = o::Inner
 

'Programming > Kotlin' 카테고리의 다른 글

Kotlin Lambda  (0) 2022.05.14
Kotlin Function  (0) 2022.05.14
Kotlin Generic  (0) 2022.04.30
Kotlin Null Safety  (0) 2022.04.23
Kotlin Loop  (0) 2022.04.23
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함