<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 反射 [TOC] 反射是這樣的一組語言和庫功能,它**允許在運行時自省你的程序的結構**。Kotlin 讓語言中的函數和屬性做為一等公民、**并對其自省(即在運行時獲悉一個名稱或者一個屬性或函數的類型**)與簡單地使用函數式或響應式風格緊密相關。 自省/內省(introspect):在運行時獲取類,屬性,函數的名稱和類型! > 在 Java 平臺上,**使用反射功能所需的運行時組件作為單獨的JAR 文件(`kotlin-reflect.jar`)分發,它不包含在kotlin標準庫中**。這樣做是為了減少不使用反射功能的應用程序所需的運行時庫的大小。如果你需要使用反射,請確保該 .jar文件添加到項目的classpath 中。 ## 類引用 最基本的反射功能是獲取 Kotlin 類的運行時引用。要獲取對靜態已知的 Kotlin 類的引用,可以使用 _類字面值_ 語法: ```kotlin val c = MyClass::class ``` 該引用是 [KClass](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/-k-class/index.html) 類型的值。 >[info]請注意,Kotlin 類引用與 Java 類引用不同。要獲得 Java 類引用,請在 `KClass` 實例上使用 `.java` 屬性。 示例: ``` fun main(args: Array<String>) { println(String::class) //輸出class kotlin.String println(String::class.java) //輸出class java.lang.String } ``` ## 綁定的類引用(自 1.1 起) 通過使用對象作為接收者,可以用相同的 `::class` 語法獲取指定對象的類的引用: ```kotlin val widget: Widget = …… assert(widget is GoodWidget) { "Bad widget: ${widget::class.qualifiedName}" } ``` 你可以獲取對象的精確類的引用,例如 `GoodWidget` 或 `BadWidget`,盡管接收者表達式的類型是 `Widget`。 ## 可調用引用 函數、屬性以及構造函數的引用,除了作為自省程序結構外,還可以用于調用或者用作[函數類型](http://www.kotlincn.net/docs/reference/lambdas.html#%E5%87%BD%E6%95%B0%E7%B1%BB%E5%9E%8B)的實例。 所有可調用引用的公共超類型是 [`KCallable<out R>`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/-k-callable/index.html),其中 `R` 是返回值類型,對于屬性是屬性類型,對于構造函數是所構造類型。 ### 函數引用 當我們有一個命名函數聲明如下: ```kotlin fun isOdd(x: Int) = x % 2 != 0 ``` 我們可以很容易地直接調用它(`isOdd(5)`),但是我們也可以將其作為一個函數類型的值,例如將其傳給另一個函數。為此,我們使用 `::` 操作符: ```kotlin fun isOdd(x: Int) = x % 2 != 0 fun main() { //sampleStart val numbers = listOf(1, 2, 3) println(numbers.filter(::isOdd)) //sampleEnd } ``` 運行結果 ``` [1, 3] ``` 這里 `::isOdd` 是函數類型 `(Int) -> Boolean` 的一個值。 >[success] [filter](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/filter.html)函數的參數類型是 (Int) -> Boolean,而isOdd函數類型也是(Int) -> Boolean, 所以程序正常運行! 函數引用屬于 [`KFunction<out R>`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/-k-function/index.html)的子類型之一,取決于參數個數,例如 `KFunction3<T1, T2, T3, R>`。 當上下文中已知函數期望的類型時,`::` 可以用于重載函數。 例如: ```kotlin fun main() { //sampleStart 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)) // 引用到 isOdd(x: Int) //sampleEnd } ``` 運行結果 ``` [1, 3] ``` 或者,你可以通過將方法引用存儲在具有顯式指定類型的變量中來提供必要的上下文: ```kotlin val predicate: (String) -> Boolean = ::isOdd // 引用到 isOdd(x: String) ``` 如果我們需要使用類的成員函數或擴展函數,它需要是限定的,例如 `String::toCharArray`。 ***** String::toCharArray 為String類型提供了一個擴展函數: String.() -> CharArray ***** 請注意,即使以擴展函數的引用來初始化一個變量,其推斷出的函數類型也會沒有接收者(它會有一個接受,接收者對象的額外參數)。如需改為帶有接收者的函數類型,請明確指定其類型: ```kotlin val isEmptyStringList: List<String>.() -> Boolean = List<String>::isEmpty ``` ### 示例:函數組合 考慮以下函數: ```kotlin fun <A, B, C> compose(f: (B) -> C, g: (A) -> B): (A) -> C { return { x -> f(g(x)) } } ``` 它返回一個傳給它的兩個函數的組合:`compose(f, g) = f(g(*))`。現在,你可以將其應用于可調用引用: ```kotlin 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() { //sampleStart fun length(s: String) = s.length val oddLength = compose(::isOdd, ::length) val strings = listOf("a", "ab", "abc") println(strings.filter(oddLength)) //等價于 println(strings.filter{ x -> isOdd(length(x)) })// 輸出 "[a, abc]" //sampleEnd } ``` 運行結果 ``` [a, abc] [a, abc] ``` ### 屬性引用(Property References) 要把屬性作為 Kotlin中 的一等對象來訪問,我們也可以使用 `::` 運算符: ```kotlin val x = 1 fun main() { println(::x.get()) println(::x.name) } ``` 運行結果 ``` 1 x ``` 表達式 `::x` 求值為 `KProperty<Int>` 類型的屬性對象,它允許我們使用`get()` 讀取它的值,或者使用 `name` 屬性來獲取屬性名。更多信息請參見[關于 `KProperty` 類的文檔](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/-k-property/index.html)。 對于可變屬性,例如 `var y = 1`,`::y` 返回 [`KMutableProperty<Int>`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/-k-mutable-property/index.html) 類型的一個值,該類型有一個 `set()` 方法。 ```kotlin var y = 1 fun main() { ::y.set(2) println(y)//2 } ``` 屬性引用可以用在不需要參數的函數處:[kotlin.collections.map](https://www.w3cschool.cn/doc_kotlin/kotlin-api-latest-jvm-stdlib-kotlin-collections-map.html) ```kotlin fun main() { //sampleStart val strs = listOf("a", "bc", "def") println(strs.map(String::length)) //sampleEnd } ``` 運行結果 ``` [1, 2, 3] ``` 要訪問屬于類的成員的屬性,我們這樣限定它:訪問類成員的屬性,可用class::prop.get/set限定它 ```kotlin fun main() { //sampleStart class A(val p: Int) val prop = A::p println(prop.get(A(1)))//1 println(A::p.get(A(1))) // 輸出 "1" //sampleEnd } ``` 對于擴展屬性:訪問類的擴展屬性,也可用class::prop.get/set限定它 ```kotlin val String.lastChar: Char get() = this[length - 1] fun main() { println(String::lastChar.get("abc"))//c } ``` ### 與 Java 反射的互操作性 在Java平臺上,標準庫包含反射類的擴展,它提供了與 Java反射對象之間映射(參見 `kotlin.reflect.jvm` 包)。 例如,要查找一個用作 Kotlin 屬性 getter 的 幕后字段或 Java方法,可以這樣寫: ```kotlin import kotlin.reflect.jvm.* class A(val p: Int) fun main() { println(A::p.javaGetter) // 輸出 "public final int A.getP()" println(A::p.javaField) // 輸出 "private final int A.p" } ``` 要獲得對應于 Java 類的 Kotlin 類,請使用 `.kotlin` 擴展屬性: ```kotlin fun getKClass(o: Any): KClass<Any> = o.javaClass.kotlin ``` ### 構造函數引用 構造函數可以像方法和屬性那樣引用。他們可以**用于期待這樣的函數類型對象的任何地方**:它與該構造函數**接受相同參數并且返回相應類型的對象**。通過**使用 `::` 操作符 + 類名**來引用構造函數。考慮下面的函數,它期待一個無參并返回 `Foo` 類型的函數參數: ```kotlin class Foo //factory: () -> Foo 代表Foo類的構造函數 fun function(factory: () -> Foo) { val x: Foo = factory() } ``` **使用 `::Foo`代表類 Foo 的零參數構造函數**,我們可以這樣簡單地調用它: ```kotlin function(::Foo) ``` 構造函數的可調用引用的類型也是[`KFunction<out R>`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/-k-function/index.html) 的子類型之一,取決于其參數個數。 ## 綁定的函數與屬性引用(自 1.1 起) 你可以引用特定對象的實例方法: ```kotlin fun main() { val numberRegex = "\\d+".toRegex()//字符串轉為正則表達式,\d轉義字符,任意一個數字 //Regex.matches:指示正則表達式是否匹配整個[輸入] println(numberRegex.matches("29"))// 輸出“true” //綁定函數引用,isNumber存儲/綁定函數引用 val isNumber = numberRegex::matches println(isNumber("29"))// 輸出“true” } ``` 取代直接調用方法 `matches` 的是**我們存儲其引用**。**這樣的引用會綁定到其接收者上。它可以直接調用(如上例所示)或者用于任何期待一個函數類型表達式的時候**: ```kotlin //直接調用函數引用 fun main() { val numberRegex = "\\d+".toRegex()//字符串轉為正則表達式 val strings = listOf("abc", "124", "a70") //過濾數字 println(strings.filter(numberRegex::matches))// 輸出“[124]” } ``` 比較綁定的類型和相應的未綁定類型的引用。綁定的可調用引用有其接收者“附加”到其上,因此接收者的類型不再是參數: ```kotlin //引用的接收者的類型不再是參數 val isNumber: (CharSequence) -> Boolean = numberRegex::matches val matches: (Regex, CharSequence) -> Boolean = Regex::matches ``` 屬性引用也可以綁定: ```kotlin fun main() { val prop = "abc"::length//length是String的屬性 println(prop.get())// 輸出“3” } ``` >[info]自 Kotlin 1.2 起,無需顯式指定 `this` 作為接收者:`this::foo` 與 `::foo` 是等價的。 ### 綁定的構造函數引用 [*inner* 類](http://www.kotlincn.net/docs/reference/nested-classes.html#%E5%86%85%E9%83%A8%E7%B1%BB)的構造函數的綁定的可調用引用可通過提供外部類的實例來獲得: ```kotlin class Outer { inner class Inner } val o = Outer() val boundInnerCtor = o::Inner ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看