Kotlin高级语法

Kotlin高级语法

委托

  • 类委托

    当一个类继承于另一个类或者实现某个接口,我们需要在该类中重写或者实现对应的方法,为了代码简练或者其他原因我们会用到委托的思想,也就是让别的类来帮助我们完成这些事情,在Kotlin中对委托进行了原生的支持,用by关键字实现。

    //将Collection的方法委托给c对象完成
    class DelegateCollection<T>(val c: Collection<T>) : Collection<T> by c {}
    
  • 属性委托

    类里面的某个成员属性也可以通过by关键字进行委托实现,但实际上只是将该属性的选择器委托给了另外一个对象也就是getter/setter,因此被委托者必须具有getValue/setValue方法。

    class Main{
    	   val p by Delegate()
    	   inner class Delegate {
            operator fun getValue(): Any {
                TODO()
            }
        }
    }
    
  • 懒加载

    懒加载其实是一个非常实用的初始化方式,他会在被使用到的地方进行实例的初始化,把一些不用立刻使用的数据放到懒加载中可以提高页面整体的运行速度。通过by lazy进行懒加载委托。

    //这样就会在用到num的地方调用getNum方法,并将返回值赋给num
    //这里其实是个lambda表达式,传过去的其实是个代码块,所以理论上可以通过任意形式返回任何对象,如方法,构造函数,代码块等等。
    //并且默认情况下是线程安全的,如果需要可以设置使用哪个锁
    val num by lazy{ getNum() }
    

反射(引用)

类引用

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

val c = MyClass::class

该引用是 KClass 类型的值。

请注意,Kotlin 类引用与 Java 类引用不同。要获得 Java 类引用, 请在 KClass 实例上使用 .java 属性。

val javaC = MyClass::class.java

除此之外还有一种:

val kProperty = MyClass::javaClass
public inline val <T : Any> T.javaClass: Class<T>
    @Suppress("UsePropertyAccessSyntax")
    get() = (this as java.lang.Object).getClass() as Class<T>

根据源码该引用获取的值应该等价于::class.java,而实际上却是个kProperty类型,着实有点让人摸不着头脑。

可调用引用

函数属性以及构造函数的引用,可以作为 lambda 函数直接被使用。

所有可调用引用的公共超类型是 KCallable, 其中 R 是返回值类型,对于属性是属性类型,对于构造函数是所构造类型。

函数引用
fun isOdd(x: Int) = x % 2 != 0

可以通过引用的形式将其转换成 lambda 函数,让我们更加简单的对其进行调用。

val numbers = listOf(1, 2, 3)
numbers.filter(::isOdd)

这里 ::isOdd 是函数类型(Int) -> Boolean的一个值。可以写成以下的形式:

val predicate: (Int) -> Boolean = ::isOdd
val numbers = listOf(1, 2, 3)
numbers.filter(predicate)
属性引用
val x = 1

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

表达式 ::x 求值为 KProperty 类型的属性对象,它允许我们使用 get() 读取它的值,或者使用 name 属性来获取属性名。更多信息请参见关于 KProperty 类的文档

用法:

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

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

java 反射的互操作性

在Java平台上,标准库包含反射类的扩展,它提供了与 Java 反射对象之间映射(参见 kotlin.reflect.jvm 包)。 例如,要查找一个用作 Kotlin 属性 getter 的 幕后字段或 Java方法,可以这样写:

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"
}

构造函数引用

构造函数可以像方法和属性那样引用。他们可以用于期待这样的函数类型对象的任何地方:它与该构造函数接受相同参数并且返回相应类型的对象。 通过使用 :: 操作符并添加类名来引用构造函数。考虑下面的函数, 它期待一个无参并返回 Foo 类型的函数参数:

class Foo

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

fun main(){
	function(::Foo)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值