Kotlin刨根问底(三):你真的懂泛型,会用吗?(上)

简介: 本文灵感来源:群友提出泛型相关的问题,感觉很多人对泛型并不是很了解~Kotlin中的泛型和Java中的泛型其实大同小异,只是语法稍微有些不同。大部分内容摘取自:《Kotlin实用指南》

0x1、要点提炼


  • 什么是泛型 →「将确定不变的类型参数化,保证集合中存储元素都是同一种


  • 泛型的好处 →「编译期类型安全检查」和「消除强类型转换,提高可读性


  • Java中泛型的使用泛型类泛型接口泛型方法


  • Java假泛型实现原理 →「类型擦除(Type Erasure)」只存在与编译期,进JVM前会擦除类型


  • Java有界泛型类型限制允许实例化的泛型类型,「extends 父类型


  • Java通配符<T>与<?>的区别(定义-形参实例化-实参)


  • 上边界通配符<? extends 父类型>父类型未知,只能读不能写,协变


  • 下边界通配符<? super 子类型>子类型未知,只能写不能读,逆变


  • 无限定通配符<?>,等价于<? extends Object>,类型完全未知,只能读不能写,不变


  • Kotlin中的型变 →「声明处型变out(协变)与in(逆变)类型映射<*>


  • Kotlin获取泛型类型匿名内部类反射实例化类型参数代替类引用内联函数


0x2、什么是泛型



0x3、Java中泛型的使用


泛型可用于类、接口和方法的创建,对应:泛型类泛型接口泛型方法,代码示例如下:



注意事项:


  • 1、泛型的参数只能是「类类型」,不能是简单数据类型(int, float等);


  • 2、泛型可以有多个泛型参数


Tips泛型类型的命名不是必须为T,也可以使用其他「单个大写字母」,没有强制的命名规范,但为了便于阅读,有一些约定成俗的命名规范:


  • 通用泛型类型:T,S,U,V


  • 集合元素泛型类型:E


  • 映射键-值泛型类型:K,V


  • 数值泛型类型:N


0x4、Java假泛型实现原理


和C#中的泛型不同,Java和Kotlin中的泛型都是假泛型,实现原理就是「类型擦除(Type Erasure)」。


Java编译器在生成Java字节码中是不包含泛型中的类型信息的,只存在于代码编译阶段,进JVM前会被擦除。


不信?写个简单的代码体验下:



运行结果如下



从输出结果可以看到获得的类型确实被擦除了,此时的「类类型」皆为ArrayList


问 → 那我们定义的泛型类型(Integer, String)到底去哪了?


答 → 被替换成了「原始类型」(字节码中的真正类型)


问 → 那原始类型具体是什么类型?


答 → 「限定类型」,无限定的话都用Object替换。


问 → ???


答 → 且听我娓娓道来~


还是上面的代码,进Java字节码看看(View -> Show Bytecode)



的确,Integer和String都被替换成了Object,那这个「限定类型」呢?写个例子试试:



看下字节码



行吧,此时的「原始类型」为「限定类型」即Animal类。


没限定类型的,都替换成Object类,也使得我们可以通过一些操作,绕过泛型


比如,我们利用「反射」往Integer类型的List插入一个String值是不会报错的:



运行结果如下



相关文章
|
6月前
|
安全 Java Kotlin
Kotlin泛型:灵活的类型参数化
Kotlin泛型:灵活的类型参数化
|
4月前
|
缓存 安全 Android开发
Android经典实战之用Kotlin泛型实现键值对缓存
本文介绍了Kotlin中泛型的基础知识与实际应用。泛型能提升代码的重用性、类型安全及可读性。文中详细解释了泛型的基本语法、泛型函数、泛型约束以及协变和逆变的概念,并通过一个数据缓存系统的实例展示了泛型的强大功能。
45 2
|
2月前
|
存储 安全 Java
Kotlin教程笔记(30) - 泛型详解
Kotlin教程笔记(30) - 泛型详解
31 3
|
2月前
|
存储 安全 Java
Kotlin教程笔记(30) - 泛型详解
Kotlin教程笔记(30) - 泛型详解
|
2月前
|
存储 安全 Java
Kotlin教程笔记(30) - 泛型详解
Kotlin教程笔记(30) - 泛型详解
25 0
|
2月前
|
存储 安全 Java
Kotlin教程笔记(30) - 泛型详解
本教程详细讲解了Kotlin中的泛型概念,包括协变、逆变、类型投影及泛型函数等内容。适合已有Java泛型基础的学习者,深入理解Kotlin泛型机制。快速学习者可参考“简洁”系列教程。
32 0
|
6月前
|
安全 Java 编译器
Android面试题之Java 泛型和Kotlin泛型
**Java泛型是JDK5引入的特性,用于编译时类型检查和安全。泛型擦除会在运行时移除类型参数,用Object或边界类型替换。这导致几个限制:不能直接创建泛型实例,不能使用instanceof,泛型数组与协变冲突,以及在静态上下文中的限制。通配符如<?>用于增强灵活性,<? extends T>只读,<? super T>只写。面试题涉及泛型原理和擦除机制。
42 3
Android面试题之Java 泛型和Kotlin泛型
|
Kotlin
Kotlin中接口、抽象类、泛型、out(协变)、in(逆变)、reified关键字的详解
Kotlin中接口、抽象类、泛型、out(协变)、in(逆变)、reified关键字的详解
102 0
|
安全 Java 编译器
Kotlin 泛型 VS Java 泛型
Kotlin 泛型 VS Java 泛型
87 0
|
存储 JSON 安全
From Java To Kotlin 2:Kotlin 类型系统与泛型终于懂了
上期主要分享了 From Java To Kotlin 1 :空安全、扩展、函数、Lambda。 这是 From Java to Kotlin 第二期。 带来 表达式思维、子类型化、类型系统、泛型。
230 0
From Java To Kotlin 2:Kotlin 类型系统与泛型终于懂了