【问题标题】:Check reified class is Parcelable or Serializable检查具体化类是 Parcelable 还是 Serializable
【发布时间】:2021-04-12 19:38:55
【问题描述】:

我已经定义了一个内联方法,它提供了一种反序列化片段参数的方法。

我需要检查请求的Arg 类型以选择反序列化方法。

inline fun <reified Arg : Any?> Fragment.navArgParser(
    crossinline parcelCreatorProducer: () -> Parcelable.Creator<Arg>
) = NavArgsLazy<Arg?>({
    arguments ?: throw IllegalStateException("Fragment $this has null arguments")
}) {
    when {
        Arg is Parcelable ->   // ISSUE
            NavArgParser.deserializeData<Arg>(it, parcelCreatorProducer.invoke())
        Arg is Serializable ->  // ISSUE
            NavArgParser.deserializeData<Serializable>(it) as Arg
        else ->
            throw IllegalStateException("${Arg::class.java.simpleName} must implement Parcelable or Serializable")
    }
}

如何检查 Arg 是 Parcelable 还是 Serializable?

【问题讨论】:

    标签: android kotlin generics parcelable kotlin-reified-type-parameters


    【解决方案1】:

    Arg 不是对象,因此您不能使用is。您应该使用接受类对象的isAssignableFrom

    when {
        Parcelable::class.java.isAssignableFrom(Arg::class.java) -> //
        ...
    }
    

    你也可以写一些扩展,比如:

    inline fun <reified L : Any, reified R : Any> isSubClassOf() = R::class.java.isAssignableFrom(L::class.java)
    
    inline fun <reified L : Any, reified R : Any> isSuperClassOf() = L::class.java.isAssignableFrom(R::class.java)
    

    并像使用它

    when{
        isSuperClassOf<Parcelable, Arg> -> //
    

    【讨论】:

    • 谢谢。我试过反之亦然(Arg::class.java as Class).isAssignableFrom(Serializable::class.java)
    • 哈哈哈,我在这里问之前犯了这个错误=)))
    【解决方案2】:

    在 Kotlin 中检查类型相等性有两种方法(没有 java 翻译):

    1. 检查一个类是否是父类的子类:
    
    inline fun <reified A> checkSubclasses(){
        if(A::class.isSubclassOf(Serializable::class)){
            println("it's a serializable")
        }
        if(A::class.isSubclassOf(Parcelable::class)){
            println("it's a parcelable")
        }
    }
    
    
    1. 找到一个类类型,然后检查类型 A 是否是 B 的子类型:
    @ExperimentalStdlibApi
    inline fun <reified A> checkType() {
        val argType = typeOf<A>()
    
        if(argType.isSubtypeOf(typeOf<Serializable>())){
            println("it's a serializable")
        } else if (argType.isSubtypeOf(typeOf<Parcelable>())){
            println("it's a parcelable")
        }
    }
    
    

    typeOf 可以在更多情况下使用 请注意typeOf 功能仍处于试验阶段。

    【讨论】:

    • 感谢您的回复。看来他们正在使用kotlin.reflect.* 包。
    猜你喜欢
    • 1970-01-01
    • 2012-03-08
    • 1970-01-01
    • 2013-01-02
    • 1970-01-01
    • 2019-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多