Kotlin / Java menggunakan enum dalam pernyataan switch tipe Int

Oct 02 2020

Untuk proyek Android, saya memiliki file .kt:

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

Dan file .java, tempat masalah terjadi:

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

Di .Idatasnya memberikan kesalahan 'Id memiliki akses pribadi di foo.animal', jadi itu tidak berfungsi.

Mengubah .Idke .getId()memberikan 'Ekspresi konstan diperlukan' karena pernyataan switch.

Ini adalah persyaratan di luar kendali saya untuk jenis yang akan digunakan intsebagai pengganti animaltanda tangan public void processAnimal(int animalId) {dan ini akan menjadi solusi yang tepat jika tidak di luar kendali saya.

Menandai bidang sebagai publik di file .kt tidak mengubah apa pun.

Adakah cara untuk mencapai apa yang ingin saya lakukan?

Terima kasih!

Jawaban

4 Alex.T Oct 02 2020 at 14:18

Satu-satunya cara yang dapat saya pikirkan untuk membuat ini berfungsi (karena keterbatasan sakelar java) adalah dengan membuat fungsi pembantu di kelas enum itu sendiri yang akan memungkinkan kita untuk menerjemahkannya Idke dalam enum Value.

Fungsi java akan menjadi:

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

Dan kelas enum akan terlihat seperti ini:

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

Cara lain untuk menulis bahwa fungsi fromInt () adalah:

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
}

Opsi kedua tidak dapat dibaca, tetapi lebih baik jika kita memiliki banyak nilai enum