Kotlin实现通用泛型工厂避免重复传递构造参数方案问询
Kotlin 泛型工厂函数实现方案
你需要的效果可以通过两种主流方案实现,都完全符合DRY原则,3和4两个参数仅在工厂函数内部定义一次,无需重复编写:
方案1:反射实现(调用形式完全匹配需求,无额外使用成本)
使用Kotlin的inline reified泛型搭配反射获取子类构造器,调用方式完全符合你要求的f<D1>()、f<D2>()形式:
import kotlin.reflect.full.primaryConstructor abstract class B { abstract val o : Int } class D1 (m: Int, n: Int) : B() { override val o = m + n } class D2 (m: Int, n: Int) : B() { override val o = m * n } // 工厂函数实现 inline fun <reified T : B> f(): T { // 直接获取泛型对应类的主构造器,传入固定参数3、4 return T::class.primaryConstructor!!.call(3, 4) }
注意事项
- 需要引入kotlin-reflect依赖,Gradle项目可以在依赖配置中添加
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - 需保证所有继承自B的子类主构造器均为接收两个Int参数的形式,否则会抛出运行时异常
方案2:无反射实现(无额外依赖,性能更优)
如果不想引入反射依赖,且子类数量相对固定,可以用when分支匹配泛型类型实现,调用形式和方案1完全一致:
abstract class B { abstract val o : Int } class D1 (m: Int, n: Int) : B() { override val o = m + n } class D2 (m: Int, n: Int) : B() { override val o = m * n } // 工厂函数实现 inline fun <reified T : B> f(): T { @Suppress("UNCHECKED_CAST") return when (T::class) { D1::class -> D1(3, 4) as T D2::class -> D2(3, 4) as T else -> throw IllegalArgumentException("不支持的子类类型") } }
注意事项
- 新增子类时需要在when分支中新增对应逻辑,成本极低
- 无任何额外依赖,运行性能比反射方案更高
选型建议
- 若子类数量多、迭代频率高,选反射方案,一次编写无需后续修改
- 若子类固定、对性能要求高,选无反射方案
内容的提问来源于stack exchange,提问作者user2297550
相关产品推荐
相关产品推荐

