如何在Kotlin中克隆对象?

问题描述 投票:19回答:4

问题很简单。

Kotlin文件describes cloning only in accessing Java and in enum class。在后一种情况下,克隆只是抛出异常。

那么,我将如何克隆任意Kotlin对象?

我应该像Java一样使用clone()吗?

kotlin clone
4个回答
21
投票

对于data class,您可以使用编译器生成的copy() method。请注意,它将执行浅拷贝。

要创建集合的副本,请使用toList()toSet()方法,具体取决于您需要的集合类型。这些方法总是创建集合的新副本;他们也执行浅拷贝。

对于其他类,没有Kotlin特定的克隆解决方案。如果符合您的要求,您可以使用.clone(),如果不符合,可以使用不同的解决方案。


9
投票

您可以使用Gson将原始对象转换为String,然后将该String转换回实际的Object类型,并且您将拥有一个克隆。看看我的例子。将此函数放在要创建克隆的类/模型中。在我的例子中,我正在克隆一个Project类型对象,所以我将它放在Project类中

class Project{
 fun clone(): Project {
                val stringProject = Gson().toJson(this, Project::class.java)
                return Gson().fromJson<Project>(stringProject, Project::class.java)
            }
}

然后像这样使用它:

val originalProject = Project()
val projectClone = originalProject.clone()

1
投票

它需要为您的类实现Cloneable,然后像公共一样覆盖clone():

public override fun clone(): Any {<your_clone_code>}

https://discuss.kotlinlang.org/t/how-to-use-cloneable/2364/3


0
投票

我已经投票给@yole以获得不错的答案,但是如果您不(或不能)使用数据类,则会采用其他方式。你可以写这样的辅助方法:

object ModelHelper {

    inline fun <reified T : Serializable> mergeFields(from: T, to: T) {
        from::class.java.declaredFields.forEach { field ->
            val isLocked = field.isAccessible
            field.isAccessible = true

            if (field.get(from) != null) {
                field.set(to, field.get(from))
            }

            field.isAccessible = isLocked
        }
    }

}

因此,您可以通过以下方式将实例A“复制”到B中:

val bInstance = AClassType()
ModelHelper.mergeFields(aInstance, bInstance)

有时,我使用这种方式将来自许多实例的数据合并到一个值可用的对象(非空)。

© www.soinside.com 2019 - 2024. All rights reserved.