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

Kotlin中如何优雅实现同名属性类实例间的值传递

Kotlin 跨类同名属性拷贝简化方案

你原代码里的compaion存在拼写错误,正确写法是companion,否则代码无法正常编译。针对大量重复的同名属性赋值场景,有以下几种常用实现方案,按需选择即可:


方案1:通用反射转换函数(零额外依赖,一次编写全项目复用)

写一个基于Kotlin反射的通用内联转换函数,自动匹配源对象和目标类主构造器的同名同类型参数,自动完成赋值,不用为每对类单独写转换逻辑:

import kotlin.reflect.full.memberProperties
import kotlin.reflect.jvm.isAccessible

inline fun <reified T : Any> Any.mapTo(): T {
    val targetConstructor = T::class.constructors.first()
    val sourcePropMap = this::class.memberProperties.associateBy { it.name }

    val constructorArgs = targetConstructor.parameters.associateWith { param ->
        val matchedProp = sourcePropMap[param.name]
        when {
            matchedProp != null && matchedProp.returnType == param.type -> {
                matchedProp.isAccessible = true
                matchedProp.get(this)
            }
            param.isOptional -> null
            else -> throw IllegalArgumentException("目标类属性${param.name}未匹配到源对象的对应同类型字段")
        }
    }

    return targetConstructor.callBy(constructorArgs.filterValues { it != null })
}

使用方式非常简单,任意对象只要属性和目标类主构造器参数名、类型匹配,就可以直接调用:

val a: A = getAFromSomewhere()
val b: B = a.mapTo<B>()

注意:该方案基于运行时反射实现,存在少量性能开销,适合非高频调用的转换场景。


方案2:编译期对象映射框架(零反射开销,适合生产级项目)

如果项目中这类转换场景很多、调用频率高,推荐使用编译期生成映射代码的对象映射框架,它会在代码编译阶段自动生成和手写逻辑完全一致的属性赋值代码,没有运行时反射开销,性能和手写工厂方法完全相同。
使用时只需要定义映射接口,框架自动完成同名属性映射:

  1. 引入依赖后定义映射接口
@Mapper
interface ModelMapper {
    fun aToB(a: A): B

    companion object {
        val INSTANCE: ModelMapper = Mappers.getMapper(ModelMapper::class.java)
    }
}
  1. 直接调用即可
val a: A = getAFromSomewhere()
val b: B = ModelMapper.INSTANCE.aToB(a)

如果存在不同名属性需要映射,只需要加@Mapping注解指定对应关系即可,不需要写全量赋值逻辑。


方案3:抽取公共属性接口(适合可修改类定义的场景)

如果多个类的重复字段完全一致,可以把公共属性抽取成顶层接口,让所有类实现该接口,转换方法可以基于公共接口编写,实现多对一/一对多的转换逻辑复用:

// 抽取公共属性接口
interface BaseModel {
    val value1: String
    val value2: String
    val value3: String
    val value4: String
    val value5: String
}

class A(
    override val value1: String,
    override val value2: String,
    override val value3: String,
    override val value4: String,
    override val value5: String,
) : BaseModel

class B(
    override val value1: String,
    override val value2: String,
    override val value3: String,
    override val value4: String,
    override val value5: String,
) : BaseModel {
    companion object {
        // 所有实现BaseModel的类都可以用这个方法转B
        fun from(source: BaseModel) = B(
            value1 = source.value1,
            value2 = source.value2,
            value3 = source.value3,
            value4 = source.value4,
            value5 = source.value5,
        )
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 03:42:17