Sintaxis de Kotlin para inferir supertipo genérico de subtipo

Al intentar llamar al código Java existente que espera una Class como parámetro, intenté codificarlo de esta manera en Kotlin:

 package com.example //Acutally imported Java code in someone elses's library abstract class JavaCode<T> { fun doTheThing(thing: Class<JavaCode<T>>) { //Does work } } //My code class KotlinCode : JavaCode<String>() { fun startTheThing() { doTheThing(KotlinCode::class.java) } // ^ Type inference failed. Expected type mismatch } 

Pero eso no se comstack con el siguiente error:

 Type inference failed. Expected type mismatch: infernetworking type is Class<KotlinCode> but Class<JavaCode<String>> was expected 

Así que traté de forzar un lanzamiento (como se sugiere en esta respuesta ):

 hello(GenericArgument::class.java as Class<Callable<String>>) 

Pero eso tiene una advertencia:

 Unchecked cast: Class<KotlinCode> to Class<JavaCode<String>> 

Entonces, ¿cuál es la syntax correcta para usar? ¿ Esto está relacionado?

Hay varios problemas en tu código.

Primero, Callable<String?> es igual a Callable<String> . Callable<String?> Significa que el argumento puede ser String o null pero Callable<String> solo es String .

Segundo, Class<GenericArgument> no implementa Class<Callable<String>> pero GenericArgument implementa Callable<String> . ellos son diferentes. Puede cambiarlo para usar genérico en su lugar.

 private fun <T : Callable<String>> hello(callable: Class<T>) { System.out.println(callable.toString()) } 

Ahora, el parámetro genérico está vinculado por Callable<String> .

En tercer lugar, callable.toString() probablemente no haga lo que desea. callable.toString() llamará a toString() de la class en lugar de object, por ejemplo, class com.example.yourclass . Si desea llamar al object toString() . Este es el correcto.

 override fun call(): String { hello(GenericArgument()) return "value" } private fun <T : Callable<String>> hello(callable: T) { System.out.println(callable.toString()) } 

Además, Kotlin permite pasar la function como parámetro o usar SAM para la interfaz. La implementación de Callable no es necesaria.

Editar: Como op actualizado la pregunta.

 @Suppress("UNCHECKED_CAST") fun <T, U : JavaCode<T>> JavaCode<T>.doTheThing2(thing: Class<U>) { doTheThing(thing as Class<JavaCode<T>>) } 
  • ¿Por qué tengo que devolver Unit.INSTANCE al implementar en Java una function Kotlin que devuelve una Unidad?
  • Ejecutando el código de kotlin dentro de un proyecto de Java
  • Clases de datos en Kotlin
  • ¿Conversión de Kotlin SAM con una interfaz Java interna privada?
  • ¿Cómo usar SQLite en Kotlin / Native?
  • String :: toByteArray () no se comstack en Kotlin
  • Kotlin utiliza la interfaz de callback de Java
  • Smart Cast no funciona como se esperaba
  • Jinq en Kotlin: ¿cómo convertir lambda en Java Serialized Lambda?
  • Choque de statement de plataforma con comparable
  • Asignación no permitida en la expresión while?