Aam*_*mir 13 java clone native object
的clone
上方法Object
,它创建的对象的精确副本,被声明为:
protected native Object clone() throws CloneNotSupportedException;
Run Code Online (Sandbox Code Playgroud)
为什么native
?
基本上,因为该clone()
方法执行了一些您无法用Java语言执行的操作:它克隆了对象的状态,包括其实际的类指定.
Java中的克隆机制基于每个类调用超类的clone
方法,一直到最后Object
.然后,Object使用这个"神奇"的本机clone
方法来复制原始对象,包括它的实际类.
想一想:
class A implements Cloneable {
public A clone() {
A obj = (A) super.clone();
// Do some deep-copying of fields
return obj;
}
}
class B extends A {
public B clone() {
B obj = (B) super.clone();
// Do some deep-copying of fields not known to A
return obj;
}
}
Run Code Online (Sandbox Code Playgroud)
现在假设你有一个B
类型对象,并调用clone
它.你希望得到一个B
对象,其内部被认为是B
,而不是Object
.B
不知道在一切的实现A
,因此它需要调用A
的clone
方法.但是,如果A
实施clone
在Java语言中,而不是调用super.clone()
,那么它将返回的对象必须是A
.它不能使用new B()
(假设在创建A时B未知).
它可以用反射做一些事情,但它如何知道要调用哪个构造函数以便所有最终字段都能正确填充?
所以诀窍是A
不会自己动手,它会调用super.clone()
,并且这一直都会回来Object
,并且它使用一个本机方法,对原始对象进行逐字节复制,调整新的堆位置.因此,新对象神奇地成为一个B
对象,类型转换不会失败.
为什么不回来Object
呢?因为那不会是克隆.当你打电话时,clone
你希望得到一个相同状态(字段)和同一个类(被覆盖和添加的方法)的对象.如果它返回了一个内部类名称为的对象,则Object
只能访问Object
提供的内容,例如toString()
,您将无法从另一个B
对象访问其私有字段,或将其分配给B
类型变量.
查看克隆文档:
否则,此方法创建此对象的类的新实例,并使用该对象的相应字段的内容初始化其所有字段,就像通过赋值一样; 这些字段的内容本身不会被克隆.
使用本机代码可以非常有效地完成此操作,因为必须直接复制某些内存.在这方面类似System.array?opy
,它也是原生的.有关详细信息,请参阅此问题:是否可以找到Java本机方法的源代码?
请注意,通常您应该避免使用Object.clone(),并使用例如复制构造函数,请参阅如何在Java中复制对象?
归档时间: |
|
查看次数: |
2573 次 |
最近记录: |