kt:reified和sam转换(Single Abstract Method Conversions)

文章讲述了Kotlin中的reified关键字如何解决泛型擦除问题,通过与inline函数结合,允许在运行时获取泛型类型信息。同时,介绍了SAM转换概念,即Kotlin如何通过Lambda表达式简化对单一抽象方法接口的调用,兼容Java的SAM接口。
摘要由CSDN通过智能技术生成

什么是refied关键字
​由于我们都知道Kotlin和Java一样都存在着泛型擦除问题,而Kotlin它知道Java所带来的这个问题,所以对此Kotlin留了一个后门,就是通过inline函数保证使得泛型类的类型实参在运行时能够保留,这样的操作 Kotlin 中把它称为实化,对应需要使用 reified 关键字。而 reified意为具体化,使得(抽象的东西)变得更加具体化,它是Kotlin所增强的一种泛型的使用方式;

当然,使用reified关键字必要条件如下:

必须是 inline 内联函数,使用 inline 关键字修饰;
泛型类定义泛型形参时必须使用 reified 关键字修饰;


reified背后的故事
​ 既然我们知道reified和inline函数是相辅相成的,使用inline函数的最大一个好处就是函数调用的性能优化和提升,需要注意的是reflied使用 inline 函数并不是因为性能的问题,而是另外一个好处它能使泛型函数类型实参进行实化,在运行时能拿到类型实参的信息,相当于带实化参数的函数每次调用都生成不同类型实参的字节码,动态插入到调用点。由于生成的字节码的类型实参引用了具体的类型,而不是类型参数所以不会存在擦除问题;

综上所述,这也是为啥reifiied关键字必须使用inline关键字修饰的原因。换句话说,使用reifled可以保证泛型类的类型实参可以在运行中被保留,由于是具体的参数类型,可有效避免了泛型擦除的问题。

sam转换

在Kotlin中,SAM的概念其实是从Java那边追溯过来的,在Java中,我们把单一方法的接口叫做SAM(Single Abstract Method)接口,从Java8之后通过Lambda可以大大简化对于SAM接口的调用。所以SAM就代表的是单一抽象方法,“SAM类型”是指像Runnable,Callable等接口;Lambda表达式其实就可以被认为是SAM类型,可以自由转换为它们。

示例:(谱写Kotlin面试指南三部曲-基础篇 - 掘金,个人实测不行)

fun main() {
    //方案一:匿名类对象
    buyCar(object : IBuy {
        override fun onBuy(money: Double) {
            println("buyCar:$money")
        }
    })

    //方案二:SAM构造方法
    buyCar(IBuy {
        println("BuyCar:$it")
    })

    //方案三:SAM构造方法(推荐)
    buyCar({
        println("BuyCar:$it")
    })

    
    //方案四:SAM构造方法(推荐)
    buyCar {
        println("BuyCar: $it")
    }
}

//买一辆一千万的车
fun buyCar(buy: IBuy) {
    buy.onBuy(10000000.0)
}

fun interface IBuy {
    fun onBuy(money: Double)
}

因此,我们借助Lambda表达式对SamType调用的优化称为SAM转换(Single Abstract Method Conversions),Kotlin对此已经兼容了Java中的SAM转换,它只是将Java的SamType翻译成了Lambda,因此在kotlin的同名方法实际变成了一个高阶函数。

个人实测报错

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值