Kotlin进阶之反射

Reflection

反射是指计算机程序在运行时(Run time)可以访问、检测和修改它本身状态或行为的一种能力。Kotlin使函数和属性成为语言中头等公民,且以近似函数式或响应式方式内省属性和函数(如运行时属性名或类型;函数名或类型)

在Java平台上,需要使用反射特性的运行时组件为独立的JAR文件(kotlin-reflect.jar),目的是降低不需要使用反射的应用包的大小。如果要使用反射,首先需要保证项目中已添加相应的.jar文件。

类引用

获取运行时类的引用时反射最基本的特性。使用class字面量语法来获取对静态已知Kotlin类引用。

val c = MyClass::class

引用为KClass类型的值

Kotlin类引用与Java类引用不一样,获取Java类引用,使用KClass实例的.java属性

约束类引用

将对象作为::class语法的接收者,来引用指定对象的类。

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

虽然接收者表达式的类型(Widget),但可获取确切的对象类引用(如:GoodWidget或BadWidget)。

函数引用

假设声明了具名函数

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

除了可以直接调用isOdd(5),还可以使用::操作符将函数作为值传给另外一个函数。

val numbers = listOf(1, 2, 3)
println(numbers.filter(::isOdd)) // 输出[1 , 3]

这里::isOdd是函数类型((Int) -> Boolean)的值

如果类型可以从上下文中推断出,::操作以重载的函数方式使用

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)函数

或者,以把方法存储到指定明确类型的变量中方式提供必要上下文信息。

val predicate: (String) -> Boolean = ::isOdd // 指向isOdd(x: String)

如果要使用类成员或扩展函数,则需要对函数进行修饰,如String::toCharArray表示String类型的扩展函数:String.() -> CharArray

范例:函数组合

假设有下面函数

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

返回两个传入两个函数的组合:compose(f, g) = f(g(*))。 应用:

fun length(s: String) = s.length

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

println(strings.filter(oddLength))  // 输出:"[a, abc]"

属性引用

Kotlin同样使用::操作符,访问Kotlin中属性。

var x = 1

fun main(args: Array<String>) {
    println(::x.get()) // 输出 "1"
    ::x.set(2)
    println(x)         // 输出 "2"
}

::x表达式赋值给KProperty<Int>类型的属性对象,可以使用get方法获取它的值,或者使用name属性检索属性名。具体信息查看KProperty类文档

对于可变属性(如:var y = 1),::y返回KMutableProperty&lt;Int&gt;类型的值,含有set方法。

属性引用可用在不需要参数的函数出

val strs = listOf("a", "bc", "def")
println(strs.map(String::length)) // 输出[1, 2, 3]

访问类成员属性

class A(val p: Int)

fun main(args: Array<String>){
    
    val prop = A::p
    println(prop.get(A(1))
}

对于扩展属性

val String.lastChar: Char
    get() = this[length - 1]
    
fun main(args: Array<String>){
    println(String::latChar.get("abc"))  // 输出 "c"
}

与Java反射交互

在Java平台上,标准库包含与Java反射对象相互映射的反射类(查看包kotlin.reflect.jvm)。如:查找backing字段或充当Kotlin属性的getter函数的Java方法。

import kotlin.reflect.jvm.*

class A(val p: Int)

fun main(args: Array<String>){
    println(A::p.javaGetter) // 输出 "public final int A.getP()"
    println(A::p.javaField)  // 输出 "private final int A.p"
}

使用.kotlin扩展属性来获取对应Java类的Kotlin类。

fun getKClass(o: Any): KClass<Any> = o.javaClass.kotlin

构造器引用

Koltin可以像函数和属性一样来引用构造器,可以用在与构造器参数相同的函数类型对象处,并返回合适类型的对象。

使用::操作符和类名引用构造器。

下面的函数为使用无参函数作为函数参数,返回类型为Foo

class Foo

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

使用::Foo(Foo类的无参构造器),则可以这样调用:

function(::Foo)

约束函数与属性引用(Kotlin 1.1)

引用可以指向特殊对象的实例方法

val numberRegex = "\\d+".toRegex();
println(numberRegex.matches("29"))  // 输出"true"

val isNumber = numberRegex::matches
println(isNumber("29"))   // 输出"true"

与直接调用matches相反,存储对函数的引用。引用与接收者绑定,可以直接在函数表达式出调用或使用。

val strings = listOf("abc" , "124" , "a70")
println(strings.filter(numberRegex::matches)) // 输出"[124]"

比较约束函数与对应未约束应用,约束引用有自己绑定的接收者,所以接收者类型不再是参数。

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

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

属性引用也可以约束

val prop = "abc"::length
println(prop.get()) // 输出"3"Kotlin进阶之反射.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《Kotlin从入门到进阶》这本书是针对Kotlin编程语言初学者和进阶者编写的,包括了Kotlin的基础知识、函数式编程、面向对象编程、Kotlin与Java的互操作性以及一些高级主题。 对于初学者而言,这本书通过一步步引导读者学习Kotlin的基础知识,如变量、数据类型、运算符、条件语句、循环语句等等。通过一些简单的例子和实践让读者逐渐掌握Kotlin的基本语法。 对于进阶者而言,本书涵盖了Kotlin的函数式编程、面向对象编程相关知识,这对于喜欢函数式编程的程序员来说是很有意义的。此外,该书还讲解了Kotlin与Java的互操作性,读者可以学习如何在Kotlin和Java之间无缝转换和互操作。 针对高级主题,本书也涉及到了Kotlin协程、Kotlin DSL等相关知识。这些高级主题对于进阶者而言是很有价值的。 总之,《Kotlin从入门到进阶》是一本适合初学者和进阶者的Kotlin编程入门书籍,它包含了Kotlin的基础知识和高级主题,通过阅读该书,读者可以逐渐掌握Kotlin编程语言,写出更加优秀的程序。 ### 回答2: 《Kotlin从入门到进阶》是一本深入介绍Kotlin编程语言的书籍,旨在帮助读者从入门到深入掌握该语言。这本书的特点是通俗易懂,适合初学者,同时也提供了一些进阶的知识,可以满足进阶者的需求。以下是该书的主要内容: 一、Kotlin基础知识的讲解。该书介绍了Kotlin的基础语法,包括变量、数据类型、运算符、条件表达式和循环语句等。 二、函数和类的使用。该书详细讲解了Kotlin中函数和类的定义和使用方法,并介绍了继承、接口等概念。同时,还提供了Kotlin中一些高级特性的介绍,如扩展函数、数据类等。 三、高级主题的深入讨论。该书对Kotlin的一些高级主题进行了深入讨论,如协程、Lambda表达式、反射、注解等。这些知识点对于想要深入掌握Kotlin的开发人员非常有用。 四、实战应用。该书提供了一些实战案例,其中包括基于Kotlin进行Android开发和Web开发的案例。这些案例将Kotlin的基本知识和高级特性与实际开发场景相结合,能够帮助开发人员更好地理解Kotlin语言的使用。 五、学习资源。该书还提供了一些学习资源,如在线文档、网站和开发工具的介绍等,这些资源能够帮助开发人员更好地学习和使用Kotlin语言。 《Kotlin从入门到进阶》是一本非常实用的Kotlin学习指南。读者可以通过该书快速掌握Kotlin的基础知识,同时还可以对Kotlin的高级特性和实战应用有更深入的了解。 ### 回答3: “Kotlin从入门到进阶”是一本介绍Kotlin语言的入门教材,适合初学者学习和入门。在书中,作者从Kotlin语言基础开始讲起,让读者了解Kotlin的语法、数据类型、循环、条件语句、函数等内容,并介绍了面向对象编程中的类、继承、接口、扩展函数等知识点。同时,书中也提供了大量的实例代码,帮助读者更好地理解Kotlin语言的使用方法。 在进阶部分中,作者将更多地介绍Kotlin语言的高级特性,如协程、注解、DSL、反射、元编程等,让读者进一步掌握Kotlin语言的使用和应用场景,并获得更深入的理解。在进阶部分中,作者也提供了许多实践案例,帮助读者将Kotlin语言应用于实际开发中。 总的来说,“Kotlin从入门到进阶”是一本非常全面的Kotlin语言教材,能够让初学者快速入门,并能够通过学习进阶部分,获得更深入的理解和应用能力。同时,书中也提供了大量实例代码和实践案例,更利于读者掌握实际开发中Kotlin的应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值