Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin / Java use enum in a switch statement of type Int

Tags:

java

kotlin

For an Android project, I have a .kt file:

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

And a .java file, where the problem occurs:

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;
    }
}

On the .Id it gives an error 'Id has private access in foo.animal', so that does not work.

Changing .Id to .getId() gives 'Constant expression required' because of the switch statement.

It is a requirement out of my control for the type to be int instead of animal in the signature public void processAnimal(int animalId) { and this would be the correct solution if it were not out of my control.

Marking fields as public in the .kt file changes nothing.

Is there a way to achieve what I am setting out to do?

Thank you!

like image 955
Karatekid430 Avatar asked Jul 07 '26 02:07

Karatekid430


1 Answers

The only way I can think of making this work (due to the java switch limitations) is to create a helper function in the enum class itself that will allow us to translate that Id into an enum Value.

The java function would be:

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;
    }
}

And the enum class would look something like this:

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
        }
    }
}}

Another way of writing that fromInt() function would be:

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
}

The second option is not as readable, but better if we have a lot of enum values

like image 181
AlexT Avatar answered Jul 08 '26 14:07

AlexT