Viv*_*pta 5 java casting kotlin
我在 kotlin 中使用安全转换选项,即as?当数据类型不兼容时,我仍然收到类转换异常,当我通过编写执行案例的通用方法执行此操作时,会发生这种情况,但是如果我直接执行转换,它会返回正如安全转换所预期的那样,为 null
class CastTest(val data: Any) {
fun castViaGenericMethod(): TypeA? {
return castToContext<TypeA>()
}
fun castDirectly(): TypeA? {
return data as? TypeA
}
private fun <CONTEXT> castToContext(): CONTEXT? = data as? CONTEXT
}
Run Code Online (Sandbox Code Playgroud)
castViaGenericMethod()->ClassCastException当数据不是 类型时,此方法将抛出异常TypeA。
->当无法进行强制转换时castDirectly()返回。null
请建议如何做到这一点。
要解决您的问题,您可以使用以下reified类型:
inline fun <reified CONTEXT> castToContext() = data as? CONTEXT
Run Code Online (Sandbox Code Playgroud)
它没有按您预期工作的原因是,泛型类型在运行时被删除。
如果我们查看字节码,我们会发现无论您的CONTEXT-generic 类型写在哪里,它都会变成java/lang/Object:
private final castToContext()Ljava/lang/Object;
L0
LINENUMBER 12 L0
ALOAD 0
GETFIELD CastTest.data : Ljava/lang/Object;
DUP
INSTANCEOF java/lang/Object // (1)
IFNE L1 // (1)
POP // (2)
ACONST_NULL // (2)
L1
ARETURN
L2
LOCALVARIABLE this LCastTest; L0 L2 0
MAXSTACK = 2
MAXLOCALS = 1
Run Code Online (Sandbox Code Playgroud)
因此,安全强制转换实际上会检查给定对象是否不是类型java/lang/Object(1),并设置要返回的值null(如果是这种情况)。但由于它是 类型java/lang/Object,因此该值只是按原样返回。然而,在调用方,字节代码如下所示:
LINENUMBER 4 L0
ALOAD 0
INVOKESPECIAL CastTest.castToContext ()Ljava/lang/Object; // the call
CHECKCAST TypeA // the type check
ARETURN
Run Code Online (Sandbox Code Playgroud)
CHECKCAST TypeA它在调用后执行附加操作castToContext,并且您会得到您的ClassCastException值,因为该值没有被取消(通用类型信息在运行时被删除)。
| 归档时间: |
|
| 查看次数: |
1653 次 |
| 最近记录: |