You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 12:47:05