日期:2014-05-20  浏览次数:20749 次

关于JAVA SE中克隆clone方法的问题
现在有如下代码
Java code
class Address
{
public String detail;
public Address(String detail)
{
this.detail = detail;
}
}

class User implements Cloneable
{
int age ;
Address address;
public User(int age)
{
this.age = age;
this.address = new Address("广州天河区");
}
public User clone() throws CloneNotSupportedException
{
return (User)super.clone();
}
}



该User类默认继承Object类,那么在方法clone中的super.clone()应该是调用的Object类中的clone()方法.我的问题是,既然调用的是父类的方法,那么在super.clone()中是如何能够得到子类的Field的信息的,从而用子类的Field信息生成一个Object对象。

同时我们都知道如下代码会出错,
Java code
class Base
{}
class Sub extends Base
{}

public class Test
{
public static void main(String args[])
{
Base base = new Base();
Sub sub = (Sub)base;
}
}



但是为什么我的第一段代码里面 (User)super.clone()却能将Object强制转换为User类,且能够正常使用呢?



此外,在重写clone()方法的时候,为什么一定要实现Cloneable接口呢,如果不实现该接口就会有异常产生,为什么?


------解决方案--------------------
首先你问super.clone()中是如何能够得到子类的Field的信息的,其实想得到信息也很容易运用反射机制就可以,只要调用在super.clone()方法中调用this.getClass()就ok了(因为clone方法是native属性,具体实现我也不清楚。),还有你问的为什么要实现Cloneable接口,其实这个相当于一个标志,单纯的表示这个类能被克隆(因为这个接口没有任何方法),因为在调用super.clone()时,会先检查这个类是否实现这个接口,否则抛出异常(这些用反射很容易实现,相信你肯定知道)。
------解决方案--------------------
探讨

引用:
我刚看了下。。不对的还请忽略。。。

首先父类很容易就能得到子类的所有信息,父类里用this.getClass()就行了。

但是父类有必要获得子类的field信息么?我感觉没什么没必要,因为父类不可能知道子类应该如何克隆。

API中有这么句话:

By convention, the returned object should be obtain……