英文:
Kotlin / Java use enum in a switch statement of type Int
问题
对于一个Android项目,我有一个 .kt 文件:
class foo () {
enum class animal (var Id: Int) {
CAT(0),
DOG(1),
FISH(2),
}
}
还有一个 .java 文件,在这里出现了问题:
public void processAnimal(int animalId) {
switch(animalId) {
case foo.animal.CAT.Id:
//做一些事情
break;
case foo.animal.DOG.Id:
//做其他一些事情
break;
case foo.animal.FISH.Id:
//做一些奇怪的事情
break;
}
}
在 .Id
上它会给出一个错误,指出 'Id 在 foo.animal 中具有私有访问权限',所以这样不起作用。
将 .Id
更改为 .getId()
会因为 switch 语句而出现 '需要常量表达式' 的错误。
对于签名 public void processAnimal(int animalId) {
,将类型设为 int
而不是 animal
是一个我无法控制的要求,如果不是这样,这将是正确的解决方案。
在 .kt 文件中将字段标记为 public 不会改变任何内容。
有没有办法实现我要做的事情?
谢谢!
英文:
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!
答案1
得分: 8
因为 Java 的 switch 语句的限制,我所能想到的唯一解决方法是在枚举类本身中创建一个帮助函数,允许我们将那个 Id
转换为枚举 Value
。
Java 函数如下:
public void processAnimal(int animalId) {
AnimalEnum animalEnum = AnimalEnum.fromInt(animalId);
switch(animalEnum) {
case CAT:
//做一些事情
break;
case DOG:
//做另一些事情
break;
case FISH:
//做一些奇怪的事情
break;
}
}
枚举类可能如下所示:
enum AnimalEnum(val Id: Int) {
CAT(0),
DOG(1),
FISH(2);
companion object {
@JvmStatic //使其从 Java 中可访问
fun fromInt(givenInt: Int): AnimalEnum {
return when (givenInt) {
CAT.Id -> CAT
DOG.Id -> DOG
FISH.Id -> FISH
else -> throw Exception("无效的 id `$givenInt`,可用的 id 为 ${values().map { it.Id }}")
}
}
}
}
写 fromInt()
函数的另一种方式如下:
companion object {
private val map = values().associateBy(AnimalEnum::Id)
@JvmStatic //使其从 Java 中可访问
fun fromInt(givenInt: Int) = map[givenInt] ?: throw Exception("无效的 id `$givenInt`,可用的 id 为 ${values().map { it.Id }}")
}
第二个选项不太易读,但在有大量枚举值的情况下更为合适。
英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论