我想在语义上限制 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答案。)