检查具体化 class 是 Parcelable 还是 Serializable

Check reified class is Parcelable or Serializable

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

而且我需要检查请求的 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?

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

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> -> //

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

  1. 检查 class 是否是父类 class 的子类:

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. 找到一个 class 类型,然后检查类型 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 功能仍处于实验阶段。