Kotlin / Java utilise enum dans une instruction switch de type Int

Oct 02 2020

Pour un projet Android, j'ai un fichier .kt:

class foo () {
    enum class animal (var Id: Int) {
        CAT(0),
        DOG(1),
        FISH(2),
    }
}

Et un fichier .java, où le problème se produit:

public void processAnimal(int animalId) {
    switch(animalId) {
        case foo.animal.CAT.Id:
            //do something
            break;
        case foo.animal.DOG.Id:
            //do something else
            break;
        case foo.animal.FISH.Id:
            //do something fishy
            break;
    }
}

Sur le, .Idil donne une erreur 'Id a un accès privé dans foo.animal', donc cela ne fonctionne pas.

Changer .Iden .getId()donne «Expression constante requise» à cause de l'instruction switch.

C'est une exigence hors de mon contrôle pour que le type soit intau lieu de animaldans la signature public void processAnimal(int animalId) {et ce serait la bonne solution si ce n'était pas hors de mon contrôle.

Le marquage des champs comme publics dans le fichier .kt ne change rien.

Y a-t-il un moyen de réaliser ce que je m'efforce de faire?

Je vous remercie!

Réponses

4 Alex.T Oct 02 2020 at 14:18

La seule façon dont je peux penser que cela fonctionne (en raison des limitations du commutateur java) est de créer une fonction d'assistance dans la classe enum elle-même qui nous permettra de traduire cela Iden une énumération Value.

La fonction java serait:

public void processAnimal(int animalId) {
    AnimalEnum animalEnum = AnimalEnum.fromInt(animalId);
    switch(animalEnum) {
        case CAT:
            //do something
            break;
        case DOG:
            //do something else
            break;
        case FISH:
            //do something fishy
            break;
    }
}

Et la classe enum ressemblerait à ceci:

enum class AnimalEnum(val Id: Int) { //classes should start with an uppercase letter in kotlin
CAT(0),
DOG(1),
FISH(2);

companion object {
    @JvmStatic //to be accessible from java
    fun fromInt(givenInt: Int): AnimalEnum {
        return when (givenInt) {
            CAT.Id -> CAT
            DOG.Id -> DOG
            FISH.Id -> FISH
            else -> throw Exception("Invalid id `$givenInt`, available ids are ${values().map { it.Id }}") // or a null or something
        }
    }
}}

Une autre façon d'écrire cette fonction fromInt () serait:

companion object {
    private val map = values().associateBy(AnimalEnum::Id)
    @JvmStatic //to be accessible from java
    fun fromInt(givenInt: Int) = map[givenInt] ?: throw Exception("Invalid id `$givenInt`, available ids are ${values().map { it.Id }}") // or a null or something
}

La deuxième option n'est pas aussi lisible, mais meilleure si nous avons beaucoup de valeurs d'énumération