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>>) } 
  • ¿No puede haber una devolución dentro de un Runnable SAM en Kotlin?
  • Anular setter para la variable definida en el constructor pnetworkingeterminado
  • Buscador privado y establecedor público para una propiedad de Kotlin
  • Kotlin: atribuye visibilidad al object complementario
  • Clase abstracta Kotlin java IllegalAccessError
  • Kotlin, estructura del proyecto
  • ¿Es posible acceder a las tipografías de Kotlin desde Java?
  • Smart Cast no funciona como se esperaba
  • Asignación no permitida en la expresión while?
  • Arquitectura del propio SDK - API de método asíncrono en Kotlin
  • ¿Delegación de constructor de Kotlin a la class de datos interna?