为什么Object.clone()在Java中是原生的? [英] Why is Object.clone() native in Java?
问题描述
clone $
方法,它创建一个对象的精确副本,声明为: Object
上的c $ c>
The clone
method on Object
, which creates an exact copy of an object, is declared as:
protected native Object clone() throws CloneNotSupportedException;
为什么原生
?
推荐答案
基本上,因为 clone()
方法做了一件你不能做的事情Java语言:它克隆了对象的状态,包括它的实际类名。
Basically, because the clone()
method does something that you cannot do in the Java language: it clones the state the of the object, including its actual class designation.
Java中的克隆机制基于调用超类的<$ c的每个类$ c> clone 方法,一直到 Object
。然后,Object使用这个神奇的原生 clone
方法来复制原始对象,包括它的实际类。
The cloning mechanism in Java is based on each class calling the superclass's clone
method, all the way up to Object
. Object then uses this "magical" native clone
method to duplicate the original object, including its actual class.
Think这个:
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;
}
}
现在想象你有一个 B
类型对象,并在其上调用 clone
。你希望得到一个 B
对象,其内部被认为是 B
,而不是对象
。 B
不知道 A
中所有内容的实现,因此需要调用一个
的克隆
方法。但是如果 A
用Java语言实现 clone
而不是调用 super.clone()
,那么它将返回的对象必须是 A
。它不能使用 new B()
(假设在创建A时B不知道。)
Now imagine that you have a B
type object, and you call clone
on it. You expect to get a B
object, whose class is internally recognized as B
, not as Object
. B
doesn't know the implementation of everything in A
, and therefore it needs to call A
's clone
method. But if A
implemented clone
in the Java language rather than calling super.clone()
, then the object it would return would have to be A
. It cannot use new B()
(assume B was not known when A was created).
它可以做有反射的东西,但它怎么知道要调用哪个构造函数以便所有最终字段都被正确填充?
It could do something with reflection, but how would it know which constructor to call so that all the final fields would be properly filled up?
所以诀窍是 A
本身不会这样做,它会调用 super.clone()
,这会一直回到 Object
,它使用一个本机方法,对原始对象进行逐字节复制,调整新的堆位置。因此,新对象神奇地变成 B
对象,类型转换不会失败。
So the trick is that A
doesn't do it itself, it calls super.clone()
, and this goes all the way back to Object
, and it uses a native method that does a byte-by-byte copying of the original object, adjusting for the new heap location. Thus, the new object magically becomes a B
object and the type casting would not fail.
为什么不返回对象
然后呢?因为那不会是克隆。当您调用 clone
时,您希望获得相同状态(字段)和相同类(重写和添加的方法)的对象。如果它返回了一个内部类名称为 Object
的对象,则只能访问 Object
提供的内容,例如 toString()
,您将无法从另一个 B
对象访问其私有字段,或者将其分配给 B
类型变量。
Why not return an Object
then? Because that would not be cloning. When you call clone
you expect to get an object of both the same state (fields), and the same class (overridden and added methods). If it returned an object whose internal class designation was Object
, you'd only have access to things that Object
offers, such as toString()
, and you would not be able to access its private fields from another B
object, or to assign it to a B
type variable.
这篇关于为什么Object.clone()在Java中是原生的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!