kotlin泛型
简介
这里介绍kotlin泛型的常用的情况
代码
class Box<E>(t: E) {
/***** 第一种 传入不同的类型**然后给 Box类 属性赋值*********/
var vaule = t //这里的vaule可以接收Int或者String类型
/***** 第二种 从方法中传入不同的类型,然后根据传入的类型运行不同的方法*********/
fun <T> doPrintln(content: T) {//在类上面可以不用 <T>(t: T) 也能编译通过
when (content) {//这里的参数不能使用传入来的 t,要使用的话,就用 vaule
is Int -> Log.d("WY+", "方法中传入了Int类型: $content")
is String -> Log.d("WY+", "方法中传入了String类型:${content.toUpperCase()}")
is Boolean -> Log.d("WY+", "方法中传入了Boolean类型:$content")
}
}
/***** 第三种 传入List<>里面装不同类型*********/
fun <T : Comparable<T>> listshow(list: List<T>) {
Log.d("WY+", "List列表(第一个): ${list[0]}")
}
/***** 第四种 传入多个类型的参数*********/
fun <T> anyType(t1: T, t2: T, t3: T, list: List<T>) {
Log.d("WY+", "t1: $t1=t2:$t2=t3:$t3=list:${list[0]}")
}
/***** 第五种 多类型参数*********/
fun <T,U> addRectangle(a: T,b: U): U{
return b
}
/***** 第六种 泛型约束** Number代表Double,Long,Int,Float,Char,Short,Byte*******/
fun <T: Number> isEqual(a: T,b: T): Boolean{
return (a == b)
}
}
在activity中使用:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
/********* 1 *传入不同的类型**然后给 Box类 属性赋值***********/
var boxInt = Box<Int>(10)//传入Int类型
var boxString = Box<String>("Runoob")//传入String类型
Log.d("WY+", "输出:" + boxInt.vaule + "/" + boxString.vaule)
/********* 2 *方法中传入不同的类型***然后根据传入的类型运行不同的方法 ***********/
boxInt.doPrintln(true)
/********* 3 *方法中传入List<>里面装不同类型**************/
boxInt.listshow(listOf(1, 2, 3))
boxInt.listshow(listOf("a", "b", "c"))
/********* 4 *任意类型的定义**************/
boxInt.anyType(1,"aa",true,listOf(3, 2, 1))
/********* 7 *任意*类型的类**************/
val a1: A<*> = A(12, "String", true)
//使用数组
val arrayList: ArrayList<*> = arrayListOf("String", 1, 1.2f, true)
for (item in arrayList){
println(item)
}
}
}
A类
/**
* 可以定义任意类型
* val a1: A<*> = A(12, "String", true)
*/
class A<T>(val t: T, val t2 : T, val t3 : T) {
}
题外
封装模块的时候遇到一种棘手情况:在一个依赖模块module_ble里提供一个对外的方法printFun,在app模块里调用printFun,把PickSelectBill作为入参,并且在printFun方法里要用到PickSelectBill里的属性值
难点:printFun方法里拿不到app里的PickSelectBill类,导致不能强转换
解决方案:
1.使用反射的方式
2.(推荐)使用Gson先转换为json字符串,然后再转为对应的bean。(前提是PickSelectBill和PrintBean的属性要一样)
使用Gson 把app的PickSelectBill转换为module_ble里的PrintBean
app的main里调用
方式一:使用反射来获取泛型里的属性
// 1.利用反射
inline fun <reified T> printProperty(obj: T, propertyName: String) {
try {
val property = T::class.java.getDeclaredField(propertyName)
property.isAccessible = true
val value = property.get(obj)
println(value)
} catch (e: Exception) {
throw Exception("类型转换错误:${e.message}")
}
}
方式二:使用Gson转换的方式
// 2.先转成json字符串,再转成PrintBean
inline fun <reified T : Any> toPrintBean(obj: T): PrintBean? {
try {
val gson = Gson()
val jsonStr = gson.toJson(obj)
return gson.fromJson(jsonStr, PrintBean::class.java)
} catch (e: Exception) {
throw Exception("类型转换错误:${e.message}")
}
}
这样就可以解决在module_ble拿不到PickSelectBill的问题