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 项目。