如何在 Kotlin 中从 Java 枚举获取名称

3

我有一个项目,使用Java和Kotlin两种语言编写,最近我遇到了下一个问题。

假设我们有一个MyMonth枚举:

public enum MyMonth {
    JAN("January"),
    FEB("February");

    private final String name;

    MyMonth(final String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

然后在 Kotlin 中,当我们打印月份的名称时:

fun main() {
    val month = MyMonth.JAN
    println(month.name)
}

我们得到:

JAN

这是在文档https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-enum/name.html中描述的内容,但实际上名称应该是January

有没有一种方法可以在Kotlin中获取Java枚举中指定的名称?

更新:我的Kotlin版本是1.3.30-release-170

更新2:IDEA甚至向我显示名称来自于Java中定义的getName()方法: enter image description here

更新3:当我们明确使用.getName()时,它可以工作,但看起来有点奇怪


你应该调用MyMonth.JAN.name,不是吗? - D. Lawrence
我的猜测是,由于 Kotlin 枚举已经有一个 name 属性,如此处所示,Java getter 和 Kotlin 属性之间存在冲突。如果可能的话,我建议将 Java 字段和 getter 的名称更改为除 namegetName() 以外的其他名称。就个人而言,我认为在 Java 枚举中命名字段为 name 是一个不好的想法,考虑到 name() 方法的存在。如果您无法更改它,那么在 Kotlin 代码中显式调用 getName() 会怎样呢? - Slaw
3个回答

5
您可以直接调用getter而不是使用属性语法:
fun main() {
    val name = MyMonth.JAN.getName()
    println(name)
}

@Orest,这是因为在枚举中name是保留字。如果您可以选择另一个属性名称,则它将不会过度。 - Nikolai Shevchenko
1
@Orest,你可以创建一个扩展属性,调用getName()方法,使其看起来更符合惯用语。 - Minn
@NikolaiShevchenko 是的,我明白了。但是我已经在评论中提到过,当你必须使用一个来自Java的带有“name”字段的枚举并且无法更改它时,这种情况并不罕见。 - Orest

3
您的Java API中有一个name字段,它是私有的。无论是在Java还是Kotlin中,都无法访问它。
如果您想要访问它,请向Java API中添加类似以下代码的内容:
public String getMonthName() { return name; }

然后从Kotlin中访问它:

val month = MyMonth.JAN.monthName

在Java中,我可以简单地添加一个getter并调用MyMonth.JAN.getName(),这将返回我所需的内容。但是,在Kotlin中并没有使用此getter,尽管IDEA向我展示它来自那里,我将更新我的问题以使其更清晰。 - Orest
嘿@Slaw,那是个好建议,不幸的是,由于我不是拥有此枚举的库的所有者,因此无法重命名该字段。此外,我认为当您拥有一个具有name字段的Java枚举时,这并不是那么罕见的情况。 - Orest
1
name 是由于已经融入到枚举定义中而特别复杂。你可能需要显式地调用 getName() 而不将它用作属性,即使 IntelliJ 告诉你不需要这样做。它可能是完全错误的。 - Louis Wasserman
是的,我明白name已经嵌入到Kotlin枚举中了,只是注意到这种奇怪的行为,有一段时间感到困惑。谢谢! - Orest

0

枚举现在使用较少。您可以使用IntDef代替枚举。

@IntDef(MyMonth.JAN, MyMonth.FEB)
@Retention(AnnotationRetention.SOURCE)
annotation class MyMonth  {
    companion object {
        const val JAN = 0
        const val FEB = 1

        fun getDisplayString(toDoFilterTypes: Int): String {
            return when (toDoFilterTypes) {
                JAN -> "All"
                FEB -> "Job"
                else -> "N/A"
            }
        }
    }
}

这似乎现在已经过时了 - https://medium.com/default-to-open/android-then-and-now-intro-intdef-enums-bca22d5cca56 - Ricky Clarkson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接