Conseguir Excepción cuando sea seguro de fundición a presión de tipo genérico en Kotlin

Vivek Gupta:

Estoy usando la opción de fundición seguro en Kotlin es decir, as?todavía estoy recibiendo excepción de difusión clase cuando los tipos de datos no son compatibles, esto sucede cuando estoy haciendo esto a través de un método genérico por escrito para llevar a cabo caso, sin embargo si realizo directamente el elenco Devuelve nula como se espera de un elenco segura

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 () -> este método lanza ClassCastException cuando no es el tipo de datos TypeA. castDirectly () -> esto devuelve null cuando el elenco no es posible.

Para sugerir cómo se puede hacer esto.

Roland:

Para solucionar el problema se podría utilizar un reifiedtipo :

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

La razón, ¿por qué no funcionó como se esperaba, es decir, que los tipos genéricos se borran en tiempo de ejecución.

Si nos fijamos en el código de bytes, vemos que en todas partes, donde su CONTEXTtipo -generic está escrito, se convierte en 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

Por lo que el elenco segura realmente hace una comprobación de si el objeto dado no es del tipo java/lang/Object(1) y establece el valor a ser devuelto a nullsi ese es el caso. Pero como es de tipo java/lang/Object, el valor se acaba de regresar como está. En el lado llamando sin embargo las miradas de código de bytes de la siguiente manera:

LINENUMBER 4 L0
ALOAD 0
INVOKESPECIAL CastTest.castToContext ()Ljava/lang/Object; // the call
CHECKCAST TypeA // the type check
ARETURN

Se hace un adicional CHECKCAST TypeAdespués de llamar castToContexty hay que obtener su ClassCastExceptioncomo el valor no fue anulado (información de tipo genérico se borró en tiempo de ejecución).

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=212043&siteId=1
Recomendado
Clasificación