Kotlin中无反射从具体化泛型获取解码标识code的方案问询
解决方案
方案1:利用具体化泛型+泛型约束(零反射、最高性能)
通过泛型约束强制Encodable实现类的伴生对象必须实现Decodable,结合具体化泛型特性,编译期直接解析伴生对象,完全规避反射:
调整接口与实现类
interface Encodable interface Decodable { val code: Int } class INT4 : Encodable { // 伴生对象实现Decodable,暴露code companion object : Decodable { override val code: Int = 1 } } class FLOAT : Encodable { companion object : Decodable { override val code: Int = 2 } }
改写decode函数
通过where约束限定T的伴生对象必须是Decodable,直接访问T.Companion.code,编译期会将泛型替换为具体类,无运行时开销:
inline fun <reified T : Encodable> decode(byteArray: ByteArray): T where T.Companion : Decodable { val code = T.Companion.code // 执行解码逻辑... return TODO("根据code和byteArray生成T实例") }
方案2:编译期生成注册表(彻底消除类引用开销)
用Kotlin注解处理器在编译期自动生成类型与解码器的映射表,运行时仅需哈希表查询,性能远优于反射:
步骤1:定义注册注解
@Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.SOURCE) annotation class RegisterCodec
步骤2:标记实现类
@RegisterCodec class INT4 : Encodable { companion object : Decodable { override val code: Int = 1 } } @RegisterCodec class FLOAT : Encodable { companion object : Decodable { override val code: Int = 2 } }
步骤3:注解处理器生成注册表
编译期自动生成映射代码(无需手动编写):
object CodecRegistry { val decoderMap = mapOf( INT4::class to INT4.Companion, FLOAT::class to FLOAT.Companion ) }
步骤4:解码函数实现
inline fun <reified T : Encodable> decode(byteArray: ByteArray): T { val decoder = CodecRegistry.decoderMap[T::class] ?: error("未注册的类型:${T::class.simpleName}") val code = decoder.code // 解码逻辑... return TODO() }
方案3:合并接口+编译期分支判断(简化结构)
如果允许调整接口结构,合并Encodable与Decodable,通过编译期when分支直接返回code,完全无反射:
合并接口与实现类
interface Codable class INT4 : Codable class FLOAT : Codable
实现code查询与解码函数
object Codec { inline fun <reified T : Codable> code(): Int = when (T::class) { INT4::class -> 1 FLOAT::class -> 2 else -> error("不支持的类型:${T::class.simpleName}") } } inline fun <reified T : Codable> decode(byteArray: ByteArray): T { val code = Codec.code<T>() // 解码逻辑... return TODO() }
该方案的缺点是新增类型时需手动更新code()方法的分支,但胜在实现简单、性能拉满。
内容的提问来源于stack exchange,提问作者Jan Vladimir Mostert
相关产品推荐
相关产品推荐

