有人可以解释java中标记接口的合约吗?
对于Ex:如果Clonable
是没有字段/方法的标记接口,那么clone()
定义在哪里?
为什么我们应该在使用Clonable
时实施clone()
i / f?
我的问题是,如果clone()
是java.lang.Object
类的方法,为什么要实施Clonable
i / f来覆盖clone()
。
有人可以详细说明这种java惯例吗?
先谢谢
答案 0 :(得分:8)
clone()
在所有类扩展的java.lang.Object
类中定义,但它是protected
。这实际上是一个具体的方法实现,它通过对象的字段克隆来执行字段,但前提是您已实现Cloneable
接口以指示允许这样做。
在实践中,许多人会覆盖clone()
方法,以便他们可以将其设为public
并允许从课外进行克隆。
这整个模式非常不寻常,而不是你通常会复制的东西,我想不出JVM中有许多其他有成对标记接口和方法的例子。从 Java 5 开始,最好为标记使用注释。例如@XmlRootElement
用于将类型标记为Jax-B可序列化(后Java 5)与用于表示类是二进制可序列化的Serializable
接口(前Java 5)。
答案 1 :(得分:4)
什么是标记界面?
不包含任何实现方法的接口称为标记或标记接口。
为何选择标记接口?
具有标记接口的基本思想是提到该类正在实现行为隐式的接口。 预计该类不会实现任何符合接口定义的合同的内容。相反,它是指示JVM隐含执行的预期功能。
Java示例
我们可以创建自定义标记界面吗?
是的,有可能。
答案 2 :(得分:1)
Clonable
不包含clone()
方法,该方法受java.lang.Object
保护。
更多可用信息here
引自Josh Bloch的有效Java:
“Cloneable接口旨在作为一个mixin接口,用于对象宣传他们允许克隆。不幸的是,它无法满足此目的......这是一种非常非典型的接口使用,而不是一个被模拟的接口。 ..为了实现接口对类产生任何影响,它及其所有超类必须遵守相当复杂,不可执行且基本上没有文档的协议“
答案 3 :(得分:1)
/**
* This method can be used to construct a [[Row]] with the given values.
*/
def apply(values: Any*): Row = new GenericRow(values.toArray)
/**
* This method can be used to construct a [[Row]] from a [[Seq]] of values.
*/
def fromSeq(values: Seq[Any]): Row = new GenericRow(values.toArray)
类是所有java类的超类/父类,
如果你想在java中创建一个对象,那么它应该是实现java.lang.object
类。
如果您没有在代码中导入Object超类,那么编译器将隐式地在您的代码中导入它。
SO自动所有属性和行为都可用于对象(程序),包括clone()方法,如果在程序中调用clone()方法,则意味着从超类(Object类)调用clone()方法,而不是来自儿童班。
标记界面: 它真正的标记接口是空接口,它不包含属性和行为。 现在,问题可能会提出来。
问。如果在我们的计划中使用,谁将实施预定义标记界面?
回答:JVM将承担这一责任,因为在JVM中定义了Marker接口功能,因此它实现并向您添加一些高级功能。
所以程序员不需要实现java.lang.object
Marker接口,JVM将承担这个责任。
答案 4 :(得分:0)
标记接口是标记类的常用技术。它们不会向类添加行为(通常)。 Clonable
接口是一个标记:每个带有Clonable
的标记的类都能够克隆自己(这就是规则)。
与Serializable
相同,虽然标记接口背后有一些隐藏的魔法(对象序列化程序查找某些方法和字段,标记的类可能实现与否)< / p>
奖励信息:忘了Clonable
,它已经破了。如果要在现实生活中创建克隆,请查找复制构造函数模式。
答案 5 :(得分:-1)
标记接口没有任何主体。它们只是要求java解释器以预定义的特定方式对扩展它们的类的对象进行操作。