一、什么是泛型
1.泛化的类型或者说是类型的抽象
2.鸭子类型在静态语言中的一种近似实现
二、泛型的实现机制
1.何为真泛型?(C#)
2.何为伪泛型?(Java,Kotlin)
三、首先来看一下JAVA和Kotlin中的伪泛性
但是如果在C#语言中,他就是真泛型了,它不仅仅存在于编译期,也存在于运行期,它是没有任何问题的。
四、在kotlin中定义泛型类和泛型方法
package com.test
/**
* @author:wangdong
* @description:泛型
*/
/**
* 为函数声明泛型
* 定义一个方法,求两个数的最大值
* 那么这两个数首先得能够比较
* 参数类型为T,返回值为T
* <T: Comparable<T>> T类型的上界是可以比较的,<T>是实参
*/
fun <T: Comparable<T>> maxOf(a:T,b:T): T{
return if (a < b) b else a
}
fun main(args: Array<String>) {
val a = 5
val b = 8
val c = maxOf(a,b)
println(c)
val complex = Complex(3.0,2.4)
val complex2 = Complex(3.0,5.0)
println(complex)
//比大小
println(maxOf(complex,complex2)) // 输出//complex2的值(3.0 + 5.0 i)
//自动推导出double
val complex3 = Complex2(5.3,6.9)
val complex4 = Complex2(4,55)
println(complex3)
println(complex4)
}
/**实现Complex接口,现在指定的是一个Double,实际上给它一个泛型T应该是更好的*/
data class Complex(val a:Double, val b: Double): Comparable<Complex>{
/**
* Compares this object with the specified object for order. Returns zero if this object is equal
* to the specified [other] object, a negative number if it's less than [other], or a positive number
* if it's greater than [other].
*/
override fun compareTo(other: Complex): Int {
return (value() - other.value()).toInt()
}
fun value():Double{
return a*a + b*b
}
/**
* Returns a string representation of the object.
*/
override fun toString(): String {
return "($a + $b i)"
}
}
/**为类声明泛型:参数泛型化*/
data class Complex2<T>(val a:T, val b: T){
/**
* Returns a string representation of the object.
*/
override fun toString(): String {
return "($a + $b i)"
}
}
五、通过kotlin的字节码分析,看看能不能获取到泛型T是什么东西
可以看到编译完,T就变成了Object了,这就是伪泛型
六、看一下JAVA和Kotlin中的伪泛型实例
import com.google.gson.Gson
import java.io.File
/**
* @author:wangdong
* @description:Java和kotlin的伪范型问题
* reifile 是让泛型参数具体化
* reifile为什么需要定义在inline函数中
* 因为kotlin和Java是伪泛型,编译完之后就没有了T,所以只能通过inline关键字,
* (接上句)将这段代码植入到调用处,才能知道参数的类型
*/
fun main(args: Array<String>) {
val person = Person("wangdong",18)
Gson().toJson(person).let{
//写的
File("person.json").writeText(it)
}
//读的
needAPerson(Gson().fromJson<Person>(File("person.json").readText()))
}
/**
* 定义一个需要person的类
*/
fun needAPerson(person: Person){
}
/**
* 看一下能不能获取到T
*/
fun <T> testGenerics(){
//把泛型打印出来,这样是打印不了的,会报错
//看一下这个T到底有没有
val t: T? = null
//println(T::class.simpleName)
}
/**
* 采用Kotlin的特性关键字inline 将方法中的泛型绑定指向调用者
* 关键字将代码植入到调用点
*/
inline fun <reified T> testGenerics2(){
println(T::class.java)
}
/**
* 给Gson定义一个拓展方法
* 通过依赖把这段代码植入到调用点
*/
inline fun <reified T> Gson.fromJson(json: String): T = fromJson(json,T::class.java)
/**
* 定义一个person类
*/
data class Person(val name: String,val age: Int){
}
七、好了,泛型到这里就结束啦。