Kotlin中泛型接口BetterEnum如何实现枚举静态方法并获取常量?
Kotlin泛型接口中给枚举类添加静态方法的解决方案
为什么直接调用T.values()不行?
values()是每个枚举类编译时单独生成的静态方法,不属于Enum父类的成员,没法通过泛型类型T直接调用;- 泛型存在类型擦除,在接口伴生对象的方法里,JVM无法获取
T的实际类型,自然找不到对应的values()方法。
方案1:传入枚举Class对象(兼容Java)
通过Class对象的enumConstants属性获取枚举常量,这是通用的跨语言兼容方案:
interface BetterEnum<T : Enum<T>> { companion object { @JvmStatic fun <T : Enum<T>> getFirstEnum(enumClass: Class<T>): T { // enumConstants返回该枚举的所有常量数组 return enumClass.enumConstants[0] } } } // 实现接口的枚举类示例 enum class Color : BetterEnum<Color> { RED, GREEN, BLUE } // 调用示例 fun main() { println(BetterEnum.getFirstEnum(Color::class.java)) // 输出 RED }
方案2:让枚举类自己提供常量源
在接口中定义抽象方法,要求枚举类返回自身的values(),再通过接口实例获取常量:
interface BetterEnum<T : Enum<T>> { // 强制实现类返回自己的枚举数组 fun getAllEnums(): Array<T> companion object { @JvmStatic fun <T : Enum<T>> getFirstEnum(enumImpl: BetterEnum<T>): T { return enumImpl.getAllEnums()[0] } } } enum class Direction : BetterEnum<Direction> { NORTH, SOUTH, EAST, WEST; override fun getAllEnums(): Array<Direction> { return values() } // 枚举类自己封装静态方法,调用更便捷 companion object { @JvmStatic fun first(): Direction { return BetterEnum.getFirstEnum(NORTH) } } } // 调用示例 fun main() { println(Direction.first()) // 输出 NORTH }
方案3:用reified泛型(Kotlin专属,不兼容Java)
如果只需要在Kotlin环境中使用,可以用reified泛型结合Kotlin标准库的enumValues()函数,省去传Class的麻烦,但不能添加@JvmStatic注解:
interface BetterEnum<T : Enum<T>> { companion object { // inline + reified 才能获取泛型的实际类型 inline fun <reified T : Enum<T>> getFirstEnum(): T { return enumValues<T>()[0] } } } enum class Fruit : BetterEnum<Fruit> { APPLE, BANANA, ORANGE } // 调用示例 fun main() { println(BetterEnum.getFirstEnum<Fruit>()) // 输出 APPLE }
注意:该方法无法被Java代码调用,因为inline reified函数不能暴露为JVM静态方法。
内容的提问来源于stack exchange,提问作者Rewwwww
相关产品推荐
相关产品推荐

