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

如何在Kotlin中克隆任意对象?官方文档相关疑问解答

How to Clone Any Kotlin Object (And Why Java's clone() Isn't the Best Bet)

Great question! Kotlin doesn’t ship with built-in clone support for its native objects, and as you noted, the official docs only mention cloning in the context of Java interop or enums (where enum clone() just throws an exception). Let’s break down the right ways to handle cloning in Kotlin, and why sticking with Java’s clone() is usually a bad idea.

First: Don’t Rely on Java’s clone() Method

Java’s clone() mechanism is notoriously flawed, and those flaws carry over to Kotlin:

  • Cloneable is a marker interface with no actual clone() method, so you have to override it manually.
  • You’re forced to handle CloneNotSupportedException even when you’ve implemented Cloneable.
  • It defaults to shallow cloning, and implementing deep cloning is clunky and error-prone.
  • Kotlin’s design encourages explicit, readable code—clone() doesn’t fit that philosophy.

Better Approaches to Clone Kotlin Objects

The cleanest way is to write explicit copy() or deepCopy() methods for your classes. This gives you full control over shallow vs deep cloning, and it’s instantly readable.

For Data Classes

Kotlin data classes automatically generate a copy() method (shallow cloning by default). If you need deep cloning, override it or add a custom deepCopy():

data class Order(val id: Int, val customer: Customer) {
    // Deep clone: copy the customer object too
    fun deepCopy(): Order {
        return this.copy(customer = customer.copy())
    }
}

data class Customer(val name: String, val address: Address) {
    fun deepCopy(): Customer {
        return this.copy(address = address.copy())
    }
}

data class Address(val street: String)

For Regular Classes

Implement a custom copy method from scratch:

class Car(val make: String, val engine: Engine) {
    // Shallow clone: engine reference stays the same
    fun copy(): Car {
        return Car(make, engine)
    }

    // Deep clone: create a new Engine instance
    fun deepCopy(): Car {
        return Car(make, engine.copy())
    }
}

class Engine(val horsepower: Int) {
    fun copy(): Engine {
        return Engine(horsepower)
    }
}

2. Serialization/Deserialization (For Universal Deep Cloning)

If you need a generic way to deep clone objects without writing custom methods, serialize the object to a byte stream and deserialize it back. This creates a completely independent copy, but has tradeoffs.

Your classes must implement Serializable:

import java.io.*

// Generic deep clone function using serialization
inline fun <reified T : Serializable> T.deepClone(): T {
    ByteArrayOutputStream().use { baos ->
        ObjectOutputStream(baos).use { oos ->
            oos.writeObject(this)
        }
        ByteArrayInputStream(baos.toByteArray()).use { bais ->
            ObjectInputStream(bais).use { ois ->
                return ois.readObject() as T
            }
        }
    }
}

// Usage example
data class Product(val id: Int, val specs: ProductSpecs) : Serializable
data class ProductSpecs(val weight: Double) : Serializable

val originalProduct = Product(123, ProductSpecs(2.5))
val clonedProduct = originalProduct.deepClone()

Note: This approach is slower than manual copy methods, and won’t work for classes that can’t be serialized (e.g., those with non-serializable properties like Thread or custom lambdas).

3. Java clone() Adaptation (Last Resort)

If you absolutely must use Java’s clone() (e.g., for interoperability with a Java library), make your Kotlin class implement Cloneable and override the method:

class Book(val title: String) : Cloneable {
    // Override clone with public access (Java's clone is protected)
    public override fun clone(): Book {
        return try {
            super.clone() as Book
        } catch (e: CloneNotSupportedException) {
            // This should never happen since we implemented Cloneable
            throw AssertionError("Clone failed unexpectedly", e)
        }
    }
}

Again, this is not recommended—stick to manual copy methods or serialization unless you have no other choice.

Final Takeaway

For most Kotlin projects, manual copy methods are the way to go: they’re readable, flexible, and align with Kotlin’s emphasis on explicit code. Serialization works for generic deep cloning, but keep an eye on performance and serialization constraints. Avoid Java’s clone() unless you’re forced to use it for interop.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:00:51