es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Error de compilación al heredar clases de Java de clases de Kotlin utilizando genéricos.

Estoy trabajando en un proyecto de Android que combina Kotlin y Java (código generado por la biblioteca Android Room). Estaba intentando hacer algunos objetos de acceso a datos genéricos.
En Kotlin, este código se compila correctamente:

data class Entity(val name: String = "")

interface ExampleBaseInterface<t: any=""> {
    fun foo(): Flow<t>
}

abstract class ExampleAbstract<t: any="">: ExampleBaseInterface<t> {
    override fun foo(): Flow<t> = TODO()
}

abstract class ExampleAbstractList<t: any="">: ExampleBaseInterface<><t>> {
    override fun foo(): Flow<><t>> = TODO()
}

class ExampleClassList: ExampleAbstractList<entity>()

Cuando uso la biblioteca Room y anoto `ExampleAbstractList` como `@Dao`, genera código Java que se parece al siguiente ejemplo. También da un error de compilación sin Room, escribiendo la clase Java manualmente.
public class ExampleJava extends ExampleAbstractList<entity>

Este código genera el error de compilación ExampleJava no es abstracto y no anula el método abstracto foo() en ExampleBaseInterface.

Si cambio foo(): Flow<><t>> en la interfaz, funciona, pero mi intención es poder usar ExampleBaseInterface recibiendo tanto T como List<t> como parámetro genérico, como en el ejemplo de Kotlin.

Me di cuenta de que con solo Kotlin funciona, y también con código Java puro que incluye la misma estructura de genéricos también funciona, me pregunto por qué no funciona cuando se combinan genéricos de Kotlin + clases hijas en Java.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El problema aquí parece estar relacionado con la forma en que Kotlin y Java manejan el borrado de tipos de manera diferente. Al usar Kotlin, el compilador puede retener la información genérica del tipo en tiempo de ejecución, lo que permite la sobrecarga correcta de funciones, mientras que con Java, el borrado de tipos elimina esta información en tiempo de ejecución, lo que provoca que el compilador no pueda diferenciar entre las diferentes funciones sobrecargadas.

    En este caso específico, el código Java generado por Android Room no sobrecarga correctamente el método foo(), lo que conduce al error de compilación en el código Java. Una posible solución sería utilizar parámetros de tipo específicos para cada método foo() deseado, evitando la necesidad de sobrecarga.

    En general, este problema resalta la importancia de diseñar cuidadosamente el código genérico al trabajar con lenguajes que tienen enfoques diferentes para el borrado de tipos, como Kotlin y Java.

Comments are closed.