web-dev-qa-db-fra.com

Classe de données Kotlin implémentant Java

J'essaie d'introduire Kotlin dans mon projet actuel. J'ai décidé de commencer par des entités, qui semblent parfaitement correspondre aux classes de données. Par exemple, j'ai une classe de données:

data class Video(val id: Long, val ownerId: Long, val title: String, val description: String? = null,
             val imgLink: String? = null, val created: Date? = null, val accessKey: String? = null,
             val views: Long? = null, val comments: Long? = null, val videoLink: String? = null): Entity

Qui implémente Java interface:

public interface Entity {
   Long getId();  
}

Mais pour une raison quelconque, le compilateur ne comprend pas que la méthode est déjà implémentée:

La classe 'Video' doit être déclarée abstraite ou implémenter un membre abstrait public abstract fun getId (): kotlin.Long! défini dans net.alfad.data.Entity

Dois-je utiliser des mots clés supplémentaires pour id param? Que signifie "!" dire dans la signature?

30
Odysseus

Le problème ici est que Kotlin charge d'abord la classe Java Entity] et voit getId comme une fonction, et non comme un getter d'une propriété. Un getter de propriété dans une classe Kotlin ne peut pas remplacer une fonction, donc la propriété id n'est pas liée en tant qu'implémentation de la fonction getId.

Pour contourner ce problème, vous devez remplacer la fonction d'origine getId dans votre classe Kotlin. Cela entraînera un conflit de signature JVM entre votre nouvelle fonction et le getter de id dans le bytecode, vous devez donc également empêcher le compilateur de générer le getter en créant la propriété private:

data class Video(
    private val id: Long,
    ...
) {
    override fun getId() = id

    ...
}

Notez que cette réponse a été adaptée à partir d'ici: https://stackoverflow.com/a/32971284/288456

38
Alexander Udalov

S'il s'agit de votre classe de données entière, vous ne remplacez pas getId (). Je vois que vous avez une propriété appelée id et Kotlin devrait générer un getter pour cela, mais qui ne sera pas marqué avec le mot-clé override dont vous avez besoin pour indiquer que vous remplacez une fonction abstraite.

- EDIT - Alexander m'a battu! Sa réponse est meilleure quand même! ;)

1
CaseyB