1. 概述

我们知道,Java 在 1.5 版本中引入了 枚举(Enum),它使得常量的处理更加类型安全、减少出错,并具备自文档化的特点。因此,Kotlin 同样也支持 枚举类型(Enum)

在本文中,我们将通过一个简短的教程,探讨如何在 Kotlin 的枚举类中创建“静态”函数。

2. 问题背景

在 Java 中,我们可以在枚举类型中添加 static 方法,用于对枚举实例进行一些通用操作。但 Kotlin 并没有 static 关键字。

因此,刚从 Java 转到 Kotlin 的开发者可能会有以下几个疑问:

  • 如何在 Kotlin 的枚举中创建“静态”函数?
  • Kotlin 中能否像 Java 一样调用这些“静态”函数?
  • 这些“静态”函数能否被 Java 调用?怎么调用?

我们将在下面通过示例逐一解答这些疑问。

为了简化演示,我们使用单元测试中的断言来验证函数调用是否返回了预期结果。

3. 在 companion object 中创建“静态”函数

我们先来看一个 Kotlin 枚举类的简单示例:

enum class MagicNumber(val value: Int) {
    ONE(1), TWO(2), THREE(3), FOUR(4), FIVE(5), SIX(6),
}

这个 MagicNumber 枚举类有一个构造函数,并定义了几个预定义的枚举实例。

要在 Kotlin 中模拟“静态”函数,我们可以通过在 companion object 中定义函数来实现。因为 companion object 中定义的函数和属性可以通过类名直接访问,例如 ClassName.functionName()

我们来为 MagicNumber 添加两个“静态”函数:

enum class MagicNumber(val value: Int) {
    ONE(1), TWO(2), THREE(3), FOUR(4), FIVE(5), SIX(6);

    companion object {

        fun pickOneRandomly(): MagicNumber {
            return values().random()
        }

        fun greaterThan(n: Int): List<MagicNumber> {
            return values().filter { it.value > n }
        }
    }
}

需要注意的是,**如果在枚举实例块之后还有其他对象或函数,则必须在最后一个枚举实例后加上分号 ;**,例如上面的 SIX(6);

现在我们写一个简单的测试来验证这些函数是否按预期工作:

assertNotNull(MagicNumber.pickOneRandomly())
assertEquals(listOf(THREE, FOUR, FIVE, SIX), MagicNumber.greaterThan(2))

测试通过,说明这两个“静态”函数已经可以正常调用。

正如你所见,由于它们定义在 companion object 中,我们可以像 Java 的静态方法一样调用它们。

接下来我们看看如何从 Java 调用这些函数。

4. 从 Java 调用 Kotlin 的“静态”函数

在 Java 中,Kotlin 枚举类的 companion object 中的函数可以通过 ClassName.Companion.functionName() 的方式调用,例如:

MagicNumber.Companion.pickOneRandomly();

但如果我们希望在 Java 中像普通静态方法那样调用(例如 MagicNumber.pickOneRandomly()),可以在函数上加上 @JvmStatic 注解。

我们为 greaterThan 函数加上 @JvmStatic 注解:

@JvmStatic
fun greaterThan(n: Int): List<MagicNumber> {
    return values().filter { it.value > n }
}

然后在 Java 中进行测试调用:

// 使用 @JvmStatic 的 greaterThan
assertEquals(Arrays.asList(THREE, FOUR, FIVE, SIX), MagicNumber.greaterThan(2));

// 通过 Companion 调用 greaterThan
assertEquals(Arrays.asList(THREE, FOUR, FIVE, SIX), MagicNumber.Companion.greaterThan(2));

// 没有使用 @JvmStatic 的 pickOneRandomly
assertNotNull(MagicNumber.Companion.pickOneRandomly());

测试通过,说明:

✅ 加了 @JvmStatic 的函数可以像 Java 静态方法一样直接调用
✅ 所有 companion object 中的函数都可以通过 Companion 对象调用,无论是否加注解
❌ 没加 @JvmStatic 的函数不能直接通过类名调用(除非通过 Companion

5. 小结

本文我们学习了如何在 Kotlin 的枚举类中创建“静态”函数,核心方式是通过 companion object 来模拟静态方法。

我们还了解了 @JvmStatic 注解的作用,它可以让 Kotlin 的“静态”函数在 Java 中像普通静态方法一样被调用。

✅ Kotlin 枚举类中没有 static 关键字,但 companion object 是等价实现
✅ 使用 @JvmStatic 可以优化 Java 调用体验
⚠️ 记得在枚举实例后加 ;,如果后面还有 companion object 或其他对象定义

如需查看完整代码,欢迎访问 GitHub 项目


原始标题:How to Create “static” methods for Enum in Kotlin