Android面试题之Kotlin泛型和reified关键字

2024-06-13 21:02:06 浏览数 (2)

代码语言:javascript复制
//泛型
class MagicBox<T>(item:T){
    var available = false
    private var subject:T = item

    fun fetch() : T? {
        return subject.takeIf { available }
    }
    //参数是匿名函数,传入T,返回R
    fun <R> fetch(subjectFunction: (T) -> R) : R? {
        return subjectFunction(subject).takeIf { available }
    }
}
class Boy(val name:String, val age:Int)
class Man(val name:String, val age:Int)
class Dog(val weight:Int)

fun main() {
    val box1 = MagicBox(Boy("java", 10))
    val box2 = MagicBox(Dog(10))
    box1.available = true
    box1.fetch()?.run {
        println("you find $name")
    }

    val man = box1.fetch {
        Man(it.name, it.age 10)
    }
    println("${man?.name}, ${man?.age}")
}

泛型in和out关键字

代码语言:javascript复制
//out
interface Production<out T>{
    fun product(): T
}

//in
interface Consumer<in T>{
    fun consume(item: T)
}

//不变
interface ProductionConsumer<T>{
    fun product():T
    fun consume(item: T)
}

open class Food
open class FastFood: Food()
class Burger : FastFood()

class FoodStore : Production<Food>{
    override fun product(): Food {
        println("Produce food")
        return Food()
    }
}
class FastFoodStore : Production<FastFood>{
    override fun product(): FastFood {
        println("Produce FastFood")
        return FastFood()
    }
}
class BurgerStore : Production<Burger>{
    override fun product(): Burger {
        println("Produce Burger")
        return Burger()
    }
}

class EveryBody: Consumer<Food>{
    override fun consume(item: Food) {
        println("consume food")
    }
}
class ModernPeople: Consumer<FastFood>{
    override fun consume(item: FastFood) {
        println("consume FastFood")
    }
}
class American: Consumer<Burger>{
    override fun consume(item: Burger) {
        println("consume FastFood")
    }
}

fun main() {
    //子类泛型对象可以赋值给父类泛型对象,用out
    val production1: Production<Food> = FoodStore()
    val production2: Production<Food> = FastFoodStore()
    val production3: Production<Food> = BurgerStore()

    //父类泛型对象可以赋值给子类泛型对象,用in
    val consumer1: Consumer<Burger> = EveryBody()
    val consumer2: Consumer<Burger> = ModernPeople()
    val consumer3: Consumer<Burger> = American()
}
reified关键字
  • 和inline一起使用,reified关键字能帮你检查泛型的参数类型。kotlin不允许对泛型参数T做类型检查,因为泛型参数类型会被类型擦除,也就是说T的类型信息在运行时是不可知的
代码语言:javascript复制
//泛型 //inline和reified关键字一起使用,以便检查泛型参数类型 
class MagicBox2<T: Human>(){
//随机产生一个对象,如果不是指定类型的对象,则通过backup生成指定类型的对象
    inline fun <reified T> randomOrBackup(backup:() -> T): T{
        val items = listOf(
            Boy2("Jav2k",30),
            Man2("John3", 45))
        val random = items.shuffled().first()
        println(random)
        return if (random is T) {
            random
        } else{
            backup()
        }
    }
}

码字不易,求转发,求点在看,求关注,感谢!

0 人点赞