kotlin 语法分析(三) -- 类引用

来源:互联网 发布:智友软件 编辑:程序博客网 时间:2024/06/14 05:47

最基本的反射功能是获取kotlin类运行时的引用,要获取静态已知的kotlin的引用,使用 类字面值 的语法:

val tag=MyClass::class 

该引用是kotlin类型的值,请注意kotlin的引用和java有所不同,要获取java类的引用,请在 MyClass 实例上使用 .java 属性

函数引用

我们声明一个函数 ,如下:

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

我们可以直接的 调用 isOdd(19), 得到一个 布尔类型的值,当然我们也可以把它当作一个值传递,例如:传递一个函数:

val nembers = listOf(1,2,3)println(nembers.fileter(::isOdd)) //将筛选的条件传递给 filter 的参数, 通过其过滤 得到结果为[1,3]

这里的函数类型 ::isOdd 是函数类型 (Int)->Boolean的值.当上下文中已知函数期望的类型时, :: 可用于重载函数. 例:

fun isOdd(x: Int) = x % 2 != 0fun isOdd(s: String) = s == "brillig" || s == "slithy" || s == "tove"val numbers = listOf(1, 2, 3)println(numbers.filter(::isOdd)) // 引用到 isOdd(x: Int)

为什么引用到的是 isOdd(x:Int)呢 ?

public inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean): List<T> {    return filterTo(ArrayList<T>(), predicate)}

通过源码可以看出,T 是根据Numbers 里面的数据类型进行决定的. 如果是 int的 就会去重载 int类型的fun ,反之怡然.

函数组合

考虑以下函数:

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

传入两个函数,返回一个 f(g(x))的组合.

fun length(s: String) = s.lengthval oddLength = compose(::isOdd, ::length)val strings = listOf("a", "ab", "abc")println(strings.filter(oddLength)) // 输出 "[a, abc]"

属性的引用

要把属性作为 kotlin中的一个对象来使用, 我们也可以使用 :: 操作符

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

表达式 ::x 求值为Kproperty 类型的对象,它允许我们通过 get()读取他们的值,或者使用name属性来获取属性名
对于可变属性,例: var a =3 ,::a 返回KMutablePreperty 类型的值,该类型有一个 set() 方法.属性的引用 可以用在不需要参数的函数处,

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

访问属于类的属性

class Test_A(var pre: Int)//调用var kpreperty=Test_A::prekpreperty.get(Test_A(10))

对于扩展性属性

val String.lastChar: Char    get() = this[length - 1] //this:代表String对象,length 是 String内部的属性fun main(args: Array<String>) {    println(String::lastChar.get("abc")) // 输出 "c" ,和 调用一个类里面的属性的方法是一样的.}

与java 反射的相互交互性

在java平台上,标准库包含反射的扩展,提供了java和 反射对象之间的映射.例: 查找一个用作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"}

要获得对应于 Java 类的 Kotlin 类,请使用 .kotlin 扩展属性:

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

构造函数的引用

构造函数的引用可以像方法和属性那样去引用

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

使用 ::Foo,类 Foo 的零参数构造函数,可以这么简单的调用它:

function(::Foo)