簡體   English   中英

在 Kotlin 中安全轉換為泛型類型時出現異常

[英]Getting Exception when Safe-Casting to Generic Type in Kotlin

我在 kotlin ie 中使用安全轉換選項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

}

castViaGenericMethod() -> 當數據不是TypeA類型時,此方法拋出ClassCastException castDirectly() -> 當無法進行castDirectly()時返回null

請建議如何做到這一點。

要解決您的問題,您可以使用reified類型

inline fun <reified CONTEXT> castToContext() = data as? CONTEXT

它沒有像您預期的那樣工作的原因是,泛型類型在運行時被刪除。

如果我們查看字節碼,我們會看到無論您的CONTEXT泛型類型寫在哪里,它都會變成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

因此,安全轉換實際上會檢查給定的對象是否不是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

它在調用castToContext之后做了一個額外的CHECKCAST TypeA並且你得到你的ClassCastException因為值沒有被取消(通用類型信息在運行時被刪除)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM