写点什么

Kotlin 学习手记 -- 泛型、泛型约束、泛型型变,天呐

用户头像
Android架构
关注
发布于: 刚刚


星投影




星投影在所有逆变点的下限类型是 Nothing, 因此不能用在属性或函数上




说白了只是一个描述符,可以简写泛型参数而已。


fun main() {


val queryMap: QueryMap<*, *> = QueryMap<String, Int>()


queryMap.getKey()


queryMap.getValue()


val f: Function<*, *> = Function<Number, Any>()


//f.invoke()


if (f is Function) {


(f as Function<Number, Any>).invoke(1, Any())


}


maxOf(1, 3)


HashMap<String, List<*>>()


//endregion


val hashMap: HashMap<*, *> = HashMap<String, Int>()


//hashMap.get()


}


class QueryMap<out K : CharSequence, out V : Any> {


fun getKey(): K = TODO()


fun getValue(): V = TODO()


}


fun <T : Comparable<T>> maxOf(a: T, b: T): T {


return if (a > b) a else b


}


class Function<in P1, in P2> {


fun invoke(p1: P1, p2: P2) = Unit


}



泛型擦除(伪泛型)




Java 与 Kotlin 实现机制一样,在运行时擦除真正的类型,C#则会真的生成一个类型去执行。


内联特化:



内联特化在调用的地方会替换到调用处,因此这时类型是确定的了,即已经特化成某个具体类型。通过 fun 前面的关键字 inline 和泛型参数 T 前面的 reified 参数两个来指定泛型参数在调用处实例化。




inline fun <reified T> genericMethod(t: T){


//val t = T()


val ts = Array<T>(3) { TODO() }


val jclass = T::class.java


val list = ArrayList<T>()


if(list is List<*>){


println(list.joinToString())


}


}


class Person(val age: Int, val name: String)


inline fun <reified T> Gson.fromJson(json: String): T = fromJson(json, T::class.java)


fun main() {


val gson = Gson()


val person2: Person = gson.fromJson("""{"age":18,"name":"Bennyhuo"}""")


val person3 = gson.fromJson<Person>("""{"age":18,"name":"Bennyhuo"}""")


}


实例:模仿的 Self Type


ty


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


pealias OnConfirm = () -> Unit


typealias OnCancel = () -> Unit


private val EmptyFunction = {}


open class Notification(


val title: String,


val content: String


)


class ConfirmNotification(


title: String,


content: String,


val onConfirm: OnConfirm,


val onCancel: OnCancel


) : Notification(title, content)


interface SelfType<Self> {


val self: Self


get() = this as Self //当前类型强转成 Self 类型


}


//泛型添加约束只能传子类


open class NotificationBuilder<Self: NotificationBuilder<Self>>: SelfType<Self> {


protected var title: String = ""


protected var content: String = ""


fun title(title: String): Self {


this.title = title


return self //返回接口的常量属性即可,运行时就是当前子类实际类型


}


fun content(content: String): Self {


this.content = content


return self


}


open fun build() = Notification(this.title, this.content)


}


class ConfirmNotificationBuilder : NotificationBuilder<ConfirmNotificationBuilder>() {


private var onConfirm: OnConfirm = EmptyFunction


private var onCancel: OnCancel = EmptyFunction


fun onConfirm(onConfirm: OnConfirm): ConfirmNotificationBuilder {


this.onConfirm = onConfirm


return this


}


fun onCancel(onCancel: OnCancel): ConfirmNotificationBuilder {


this.onCancel = onCancel


return this


}


override fun build() = ConfirmNotification(title, content, onConfirm, onCancel)


}


fun main() {


ConfirmNotificationBuilder()


.title("Hello")


.onCancel {


println("onCancel")


}.content("World")


.onConfirm {


println("onConfirmed")


}


.build()


.onConfirm()


}


如果不定义 SelfType 类型,则子类在调用 ConfirmNotificationBuilder().title(“Hello”)之后不能再继续调用子类的 onCancel 方法,因为返回的是父类型,但是实际运行时这个类型是子类型。


实例: 基于泛型实现 Model 实例的注入


import java.util.concurrent.ConcurrentHashMap


import kotlin.reflect.KProperty


abstract class AbsModel {


init {


Models.run { this@AbsModel.register() }


}


}


class DatabaseModel : AbsModel() {


fun query(sql: String): Int = 0


}


class NetworkModel : AbsModel() {


fun get(url: String): String = """{"code": 0}"""


}


class SpModel : AbsModel() {


init {


Models.run { register("SpModel2") }


}


fun hello() = println("HelloWorld")


}


object Models {


private val modelMap = ConcurrentHashMap<String, AbsModel>()


fun AbsModel.register(name: String = this.javaClass.simpleName) {


modelMap[name] = this


}


//String 扩展函数


fun <T: AbsModel> String.get(): T {


return modelMap[this] as T


}


}


fun initModels() {


DatabaseModel()


NetworkModel()


SpModel()

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Kotlin学习手记--泛型、泛型约束、泛型型变,天呐