Kotlin(反射)学习笔记

反射

反射是一系列语言和库的特性,允许在运行是获取你代码结构。 Kotlin 把函数和属性作为语言的头等类,而且反射它们和使用函数式编程或反应是编程风格很像。

类引用

最基本的反射特性就是得到运行时的类引用。要获取引用并使之成为静态类可以使用字面类语法:

val c = MyClass::class

引用是一种 KClass类型的值。你可以使用 KClass.propertiesKClass.extensionProperties 获取类和父类的所有属性引用的列表。

注意这与 java 类的引用是不一样的。参看 java interop section

函数引用

当有一个像下面这样的函数声明时:

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

我们可以通过 isOdd(5) 轻松调用,同样我们也可以把它作为一个值传递给其它函数。我们可以使用 :: 操作符

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

注意现在 :: 操作符右边不能用语重载函数。将来,我们计划提供一个语法明确参数类型这样就可以使用明确的重载函数了。
如果需要使用一系列类,或者扩展函数,必须是需合格的,并且结果是扩展函数类型,比如。String::toCharArray 就带来一个 String: String.() -> CharArray 类型的扩展函数。

函数组合

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

它返回一个由俩个传递进去的函数的组合。现在你可以把它用在可调用的引用上了:

fun length(s: String) = s.size
val oddLength = compose(::isOdd, ::length)
val strings = listOf("a", "ab", "abc")

println(strings.filter(oddLength)) // Prints "[a, abc]"

属性引用

在 kotlin 中访问顶级类的属性,我们也可以使用 :: 操作符:

var x = 1
fun main(args: Array<String>) {
    println(::x.get())
    ::x.set(2)
    println(x)
}

::x 表达式评估为 KProperty<Int> 类型的属性,它允许我们使用 get() 读它的值或者使用名字取回它的属性。更多请参看docs on the KProperty class

对于可变的属性比如 var y =1,::y返回类型为 [KMutableProperty<Int>](http://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/-k-mutable-property.html),它有 set()方法

访问一个类的属性成员,我们这样修饰:

class A(val p: Int)

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

对于扩展属性:

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

fun main(args: Array<String>) {
  println(String::lastChar.get("abc")) // prints "c"
}

与 java 反射调用

在 java 平台上,标准库包括反射类的扩展,提供了到 java 反射对象的映射(参看 kotlin.reflect.jvm 包)。比如,想找到一个备用字段或者 java getter 方法,你可以这样写:

import kotlin.reflect.jvm.*

class A(val p: Int)

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

构造函数引用

构造函数可以像方法或属性那样引用。只需要使用 :: 操作符并加上类名。下面的函数是一个没有参数并且返回类型是 Foo:

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

我们可以像下面这样使用:

function(:: Foo)
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 不重要的废话 前段时间看了一遍《Programming Kotlin》,主要目的是想提高自己的英文阅读能力,能力提...
    珞泽珈群阅读 8,787评论 1 7
  • 原由: 笔者在很久之前都有提升学历的想法,但是每次一搜索都各种广告信息,加上继续教育的形式多,变化大,看得一头雾水...
    落影随光阅读 4,871评论 0 0
  • 哈喽,周末愉快。时间过得好快。一周的学习就这样结束,回想起第一天学习的时候。我们二班选班长的时候。我主动站出来担任...
    宝贝奇奇阅读 1,328评论 0 0
  • “你走吧 不舍还你 自由还你 最甜美的关于你的梦还你 六月的傍晚还你 第一次拥抱和最后一次亲吻还你 肩...
    是草莓啊阅读 1,454评论 0 0

友情链接更多精彩内容