java的clone方法

class Employee implements Cloneable
{
public Employee clone() throws CloneSupportedException
{
return (Employee)super.clone();
}
}
我不明白为什么调用super.clone()方法能否经过转换后就能生成一个Employee的副本,它不是生成一个object的副本吗?
【public interface Cloneable此类实现了 Cloneable 接口,以指示 Object.clone() 方法可以合法地对该类实例进行按字段复制。】
这个句话是什么意思,能否具体说明下!
调用super.clone()等价于object.clone()吗?
super.clone()不就是构造一个object对象的副本吗?为什么能够构造employee对象的副本!
--------------------------
二楼回答的非常好,能否详细解释下super.clone()不能用object.clone()代替吗?

1.Object中的clone执行的时候使用了RTTI(run-time type identification)的机制,动态得找到目前正在调用clone方法的那个reference,根据它的大小申请内存空间,然后进行bitwise的复制,将该对象的内存空间完全复制到新的空间中去,从而达到shallowcopy的目的。
所以你调用super.clone() 得到的是当前调用类的副本,而不是父类的副本。
2.这句话是J2SE API帮助里面的话,意思是要让实例调用clone方法就需要让此类实现Cloneable接口,API里面还有句话是:如果在没有实现 Cloneable 接口的实例上调用 Object 的 clone 方法,则会导致抛出 CloneNotSupportedException 异常,这便是“合法”的含义。 但请注意,Cloneable接口只是个标签接口,不含任何需要实现的方法,就像Serializable接口一样。

3. Object.clone()? 不能这么调用的。

回答还满意么。

/*------------------以下是对问题的补充---悲哀的注释------------*/

ok 请容我慢慢道来
你看到clone()是Object的方法,而Object是所有类的父类,就认为可以用Object调用 clone是么?
但不能使用Object调用clone()方法
原因如下:
1.从你写法本身来看,Object.clone()肯定不行,因为Object是类, 而clone()是成员方法,所以不能用Object.clone();
2.那么是不是可以先Object obj=new Object();再obj.clone();或者Object.class.newInstance().clone()呢?还是不行。
clone()对Object类对象本身是不可见的。所以你会发现找不到clone()方法
原因是:clone()方法是protected访问权限
方法原型:protected native java.lang.Object clone() throws java.lang.CloneNotSupportedException
而protected权限的含义是:只对同一包中的类和不同包中的子类及间接子类可访问,换句话说就是不同包中的非子类或间接子类不能访问,包含了默认的包访问权限。
这个地方容易混淆哦
你可能会问任何类都是Object的子类为什么不能访问呢,对,任何类是他的子类也继承了clone()方法
但请注意,你那句代码clone()的调用者是谁?是Object本身,即Object对象,正如我们所说,“不同包中的非子类或间接子类不能访问”,这里面也包括了父类本身,你调用者是父类,在不同包中,protected成员对父类不可见哦,所以根本不能用object对象调用clone()

综上,因为在不同包中父类本身不能调用,也找不到protected方法 ,故无法在代码中使用object直接调用clone()方法,

有点难理解,关键在对protected的理解上,因为protected除了本身在继承上的访问权限外,还包含了包访问权限,希望回答你还满意。
温馨提示:答案为网友推荐,仅供参考
第1个回答  推荐于2017-09-15

  Java语言的一个优点就是取消了指针的概念,但也导致了许多程序员在编程中常常忽略了对象与引用的区别,特别是先学c、c++后学java的程序员。并且由于Java不能通过简单的赋值来解决对象复制的问题,在开发过程中,也常常要要应用clone()方法来复制对象。比如函数参数类型是自定义的类时,此时便是引用传递而不是值传递。以下是一个小例子:

public class A {
public String name;
}
public class testClone {

public void changeA(A a){
a.name="b";
}
public void changInt(int i){
i=i*2+100;
}

/**
 * @param args
 */
public static void main(String[] args) {
// TODO Auto-generated method stub
testClone test=new testClone();
A a=new A();
a.name="a";
System.out.println("before change : a.name="+a.name);
test.changeA(a);
System.out.println("after  change : a.name="+a.name);
int i=1;
System.out.println("before change : i="+i);
test.changInt(i);
System.out.println("after  change : i="+i);
}

}

第2个回答  2009-08-25
这句话的意思是 要想rewrite clone方法 必须是该类实现Cloneable接口,就是你的Employee要实现这个接口。
另外你不能这么理解“调用super.clone()方法能否经过转换后就能生成一个Employee的副本”,照你这样理解:
public Employee(){super();} 这样构造方法岂不是实例化了一个父类对象?
第3个回答  2009-08-25
class Employee implements Cloneable
{
int i;
String[] ss;

public Employee clone() throws CloneNotSupportedException
{

//这里建议你调用一下下面的输出语句
System.out.println(super.clone().getClass());
System.out.println(super.clone() instanceof Employee);

//标准做法
Employee clone = new Employee();
clone.i = this.i;
clone.ss = this.ss.clone();
return clone;

}

}

super.clone() 确实返回一个 Object 对象。
你的问题在于 对 类型强转 的理解,
父类对象是不能强转为子类对象的。
建议强转时 先使用 instanceof 进行判断。
相似回答