Kotlin泛型实例化学习记录

最近在按照第三行代码书上的内容写sunnyWeather项目,前几天明明刚看的泛型初始化,今天再看一遍,又一脸懵逼了,还是记录一下吧,在记录的过程中加强记忆。

在Android项目中,通常使用Retrofit框架来请求网络,在没有使用Kotlin特性之前,通常是这样写的。

object BaseHttpHelper {

    private val retrofit: Retrofit by lazy {
        Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create())
            .baseUrl(Const.BASE_URL)
            .build()
    }

    public fun <T> getApiService(serviceClass: Class<T>): T {
        return retrofit.create(serviceClass)
    }
}

然后在使用的地方这样写即可

BaseHttpHelper.getApiService(PlaceService::class.java)

然后我们来使用泛型实例化。
在Java中泛型由于有类型擦除的存在,所以不允许我们对泛型的类型进行判断或是进行一些操作,所以如果我们想要对getApiService()方法再精简一些,这样写,代码就会报错

    fun <T> getApiService(): T {
        return retrofit.create(T::class.java)
    }

错误信息为:Cannot use T as reified type parameter.use a class instead。
也就是T不能作为具体化类型的参数,而要使用一个class类。

那我们应该怎么改呢? 使用reified关键字,使用了这个关键字以后我们就可以在函数参数中写T::class.java了。
注意,reified关键字只允许在kotlin内联函数中使用,为什么呢?我们先看优化以后的代码再讲为什么。

object ServiceCreator {
    private val retrofit = Retrofit.Builder()
        .baseUrl(Const.BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .build()

    fun <T> create(serviceClass: Class<T>): T = retrofit.create(serviceClass)

    inline fun <reified T> create(): T = create(T::class.java)
}

我们在调用的位置直接写

val placeService = ServiceCreator.create<PlaceService>()

即可。为什么呢?因为内联啊,实际上内联函数就是在调用的位置把整个函数给搬过去了,上面的代码实际上就等于

val placeService = ServiceCreator.create(PlaceService::class.java)

所以说可以这样写,实际上kotlin并没有对java做出突破,它只是在java的基础上添加了很多语法小技巧,可以方便我们开发者写更少一点的代码,达到相同的效果。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值