为什么Object.clone()在Java中是原生的? [英] Why is Object.clone() native in Java?

查看:128
本文介绍了为什么Object.clone()在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆