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 次 |
| 最近记录: |