如何在Kotlin中克隆对象?

Dim*_*ims 27 clone kotlin

问题很简单.

Kotlin文档仅描述了在访问Java和枚举类时的克隆.在后一种情况下,克隆只是抛出异常.

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

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

yol*_*ole 29

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

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

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

  • @yole:是否有记录/保证“toSet()”返回一个新实例?这似乎就是目前的实现方式,但[库文档](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/to-set.html)只说它返回一个放。如果它不是图书馆合同的一部分,我有点犹豫是否要依赖这种行为。 (2认同)

Gib*_*olt 16

使用 Kotlindata class很容易克隆.copy()

所有值都是浅复制的,一定要小心处理任何列表/数组内容。

的一个有用功能.copy()是能够在复制时更改任何值。有了这个类:

data class MyData(
    val count: Int,
    val peanuts: Int?,
    val name: String
)
val data = MyData(1, null, "Monkey")
Run Code Online (Sandbox Code Playgroud)

您可以为任何属性设置值

val copy = data.copy(peanuts = 100, name = "Elephant")
Run Code Online (Sandbox Code Playgroud)

结果copy将具有值(1, 100, "Elephant")


zul*_*hah 13

您可以使用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)
            }
}
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它:

val originalProject = Project()
val projectClone = originalProject.clone()
Run Code Online (Sandbox Code Playgroud)

  • 天哪,请永远不要这样做。它带来了*巨大*的开销。 (4认同)
  • @PauloMerson,您可以在这里找到最近的性能测试:https://www.baeldung.com/java-performance-mapping-frameworks;gson 的速度大约是该测试中最慢执行者的两倍,并且必须同时进行序列化和反序列化。是的,开销可能会慢 100 倍! (4认同)
  • 看起来很笨拙,但很适合创建测试对象的克隆 (2认同)

小智 6

它需要为您的类实现 Cloneable,然后将 clone() 重写为 public,如下所示:

public override fun clone(): Any {<your_clone_code>}
Run Code Online (Sandbox Code Playgroud)

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


Hor*_*tio 5

如果您尝试克隆的类没有实现Cloneable或不是数据类并且是外部库的一部分,您可以创建一个返回新实例的扩展方法。例如:

class Person {
  var id: String? = null
  var name: String? = null
} 
fun Person.clone(): Person {
  val person = Person()
  person.id = id
  person.name = name
  return person 
}
Run Code Online (Sandbox Code Playgroud)