如何通过Kotlin具体化泛型将字符串转换为对应枚举类型?
问题描述
我正在开发一个处理应用字符串属性的API,这些属性可转换为Enum、Int、String等类型。我写了一个Configuration工具类,但在枚举转换分支不知道如何通过具体化泛型把字符串转成对应枚举实例。
现有代码如下:
object Configuration { inline fun <reified T> get(context: Context, propertyName: String): T { val propertyStringValue = context.config[propertyName] ?: throw InvalidConfigurationException("Unable to access property $propertyName") if (T::class.isSubclassOf(Enum::class)) { // 这里如何通过类名将字符串转为枚举实例? } else if (T::class.isSubclassOf(String::class)) { // 转成字符串 } else if (T::class.isSubclassOf(Integer::class)) { // 转成整数 } } } enum class BuildingLevel{ FIRST, SECOND, // ... } enum class StreetType { OPEN, ISOLATED, // ... }
已知context.config["STREET_TYPE"]返回字符串OPEN,期望:
Configuration.get<StreetType>(context, "STREET_TYPE")返回枚举实例StreetType.OPENConfiguration.get<String>(context, "STREET_TYPE")返回字符串OPEN
解决方案
枚举转换实现
因为泛型T是**具体化(reified)**的,可直接使用Kotlin标准库函数enumValueOf<T>()完成字符串到枚举实例的转换,该函数会根据传入的字符串名称返回对应枚举类的实例。
需要注意捕获字符串无法匹配枚举常量的异常,建议包装成自定义的InvalidConfigurationException,保持异常类型统一。
其他类型分支优化
- String类型:直接返回原始字符串即可,无需额外转换
- Int类型:调用
toInt()转换,同样需要处理转换失败的异常
修改后完整代码
object Configuration { inline fun <reified T> get(context: Context, propertyName: String): T { val propertyStringValue = context.config[propertyName] ?: throw InvalidConfigurationException("Unable to access property $propertyName") return try { when { T::class.isSubclassOf(Enum::class) -> enumValueOf<T>(propertyStringValue) T::class == String::class -> propertyStringValue as T T::class == Int::class -> propertyStringValue.toInt() as T else -> throw InvalidConfigurationException("Unsupported type ${T::class.simpleName} for property $propertyName") } } catch (e: IllegalArgumentException) { throw InvalidConfigurationException("Failed to convert value '$propertyStringValue' to type ${T::class.simpleName} for property $propertyName", e) } } } class InvalidConfigurationException(message: String, cause: Throwable? = null) : Exception(message, cause) enum class BuildingLevel{ FIRST, SECOND, // ... } enum class StreetType { OPEN, ISOLATED, // ... }
使用示例
// 获取枚举实例 val streetType = Configuration.get<StreetType>(context, "STREET_TYPE") // 返回 StreetType.OPEN // 获取字符串 val streetTypeStr = Configuration.get<String>(context, "STREET_TYPE") // 返回 "OPEN" // 获取整数(假设对应属性值为数字字符串) val floor = Configuration.get<Int>(context, "BUILDING_FLOOR") // 示例返回 1
内容的提问来源于stack exchange,提问作者mr.nothing
相关产品推荐
相关产品推荐

