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

Kotlin函数返回匿名对象的类型推导及泛型惯用写法问题

匿名对象返回类型的自动推断规则

Kotlin对匿名对象的类型推断有明确限制:

  • 只有当函数为私有(private) 或局部函数时,返回的匿名对象的实际类型才会被保留,自定义的with方法可以被正常识别
  • 若函数为公有、保护、内部修饰的,返回的匿名对象类型会被自动向上擦除为Any,无法识别到匿名对象内部的自定义方法

如果having函数只需要在当前文件/当前类内部使用,只要给函数加上private修饰即可直接解决类型识别问题,不需要单独抽取独立类。另外注意Class.newInstance()在高版本Kotlin/Java中已被废弃,推荐替换为getDeclaredConstructor().newInstance()兼容无参构造场景。

泛型写法的优化建议

当前传入Class<T>的写法是Java的惯用实现,Kotlin更推荐使用实化类型参数(reified) 优化,不需要手动传入类对象,DSL调用会更简洁:

// 搭配inline + reified 不需要传Class参数
private inline fun <reified T> having() = object {
    infix fun with(fn: T.() -> Unit) = T::class.java.getDeclaredConstructor().newInstance().apply(fn)
}

fun test() {
    // 调用时直接指定泛型即可,无需传入::class.java
    having<Pizza>() with {
        size = Size.NORMAL
        cheese = Cheese.MOZARELLA
    }
}

如果模型类均包含公开无参构造,上述写法可满足需求。如果不想依赖反射实现,更推荐无反射的通用Builder写法,完全符合Kotlin惯用规范,无额外性能开销:

inline fun <T> build(instance: T, fn: T.() -> Unit): T = instance.apply(fn)

// 调用示例
fun test() {
    build(Pizza()) {
        size = Size.NORMAL
        cheese = Cheese.MOZARELLA
    }
}

内容的提问来源于stack exchange,提问作者Tuomas Toivonen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 08:06:04