我想在语义上限制 map ,使其仅接受“数据”类对象类型作为kotlin中的值,如下所示:

class Test(
    val test : Int
)

data class Test2 (
    val test : Int
)

fun test(map : Map<String, /* compile error on Test, but accept Test2 or any other data class */>) {
}

我主要是想这样做,以便可以将 map 中的所有内容保持可复制状态,但是当我这样做时:
fun <T: Cloneable> test(map : Map<String, T>) {
     // test clone
     map.map { it.key.uuid to it.value.clone() } .toMap() // error on .clone() Cannot access 'clone': it is protected in 'Cloneable'
}

但我认为实现Cloneable接口(interface)会使您的克隆方法公开吗?本质上,我在寻找编译时保证在该方法调用中所有数据都是可复制的(是原始类型,可以调用.copy()的数据类或实现了Cloneable的任何对象)。是我唯一的选择反射和运行时断言吗?

最佳答案



不,它只是一个标记器接口(interface),它告诉 protected Object.clone()方法不要抛出CloneNotSupportedException。实际上,实现Cloneable的类通常会覆盖clone()并将其公开,但这不是必须的。当然,如果您不知道确切的类型,那也没有帮助!

克隆机制是Java的早期部分,并且设计得不太好。 (Effective Java称其为“接口(interface)的一种非常非典型的用法,而不是要被模仿的一种。”)但是它仍然被使用,因此我们一直坚持下去……

(另请参见these related答案。)

10-07 15:56