如何在Kotlin中基于Java实现用JOOQ构建动态Condition生成器?
解决Kotlin中JOOQ TableField Map的泛型问题
问题根源
Java代码里的Map<String, TableField<?, ?>>转Kotlin时,Kotlin会默认把通配符转为out协变(即Map<String, out TableField<*, *>>),但TableField的eq()、lt()等方法需要逆变的泛型支持(要接收对应类型的值作为参数),协变的out修饰会导致无法调用这些方法。
正确的Map声明方式
直接声明为val fieldMap: Map<String, TableField<*, *>>即可,不要加out。Kotlin里的*通配符和Java的?不完全等价,这里直接用TableField<*, *>就能保留和Java一样的灵活性,同时允许调用eq()等方法。
示例代码
import org.jooq.Condition import org.jooq.TableField // 初始化Map,存入TableField对象 val fieldMap: Map<String, TableField<*, *>> = mapOf( "id" to USER.ID, "name" to USER.NAME, "age" to USER.AGE ) // 动态构建Condition的方法 fun buildCondition(fieldName: String, value: Any): Condition? { val field = fieldMap[fieldName] ?: return null // 这里可以安全调用eq()方法 return when (field.type) { Int::class.java -> field.eq(value as Int) String::class.java -> field.eq(value as String) // 其他类型按需添加 else -> null } }
额外类型安全优化
如果需要更严格的类型安全,避免显式类型转换,可以用reified泛型配合扩展函数:
inline fun <reified T> getCondition(fieldName: String, value: T): Condition? { val field = fieldMap[fieldName] as? TableField<*, T> ?: return null return field.eq(value) }
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

