调用super时进行java向下转换。clone()方法
考虑以下程序
class A implements Cloneable {
String str = null;
public void set(String str)
{
this.str = str;
}
@Override
public A clone()
{
A a = null;
try {
a = (A) super.clone();
if(a.str!=null) {
System.out.println(a.str);
}
else {
System.out.println("null");
}
}
catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return a;
}
public static void main (String args[])
{
A a = new A();
a.set("1234");
A b = a.clone();
}
}
为什么上述程序的输出为1234且不为空
我希望为空,因为我的理解如下
太好了。clone()方法将创建一个父类型的新对象(本例中为object),父类的属性将在其中被浅层复制
当我们在clone()方法中进行向下转换时,子类中定义的属性将使用它们的默认值进行初始化,因为这是一个新对象
但在查看输出后,似乎子类(this)的当前实例的属性值被复制到新构造的对象(在调用父类的克隆并向下转换之后)
有人能告诉我当我们情绪低落时发生了什么吗
# 1 楼答案
来自Object#clone文档
如你所见,典型的情况是
X.equals(XClone) == true
。 对您来说,情况并非如此,因为A
没有覆盖equals
方法此外:
正如本文档所述,本机实现只会创建您试图克隆的对象的
shallow copy
。由于这种行为,正确的输出是1234
,而不是null
,因为类中的fields
刚刚分配给克隆实例# 2 楼答案
1234是正确的结果。。。让我们看看原因:
创建一个新的
A
实例:将值设置为
A.str
克隆a
首先,请注意,我们正在使用实例
a
中的clone()
方法,所以让我们转到这里:# 3 楼答案
不,这就是你的错误所在
Object.clone()
将创建一个新的运行时类实例,该实例与被调用对象的运行时类相同,即A
,而不是Object
。它会将被调用对象中A
的所有字段浅拷贝到新对象中这没有任何意义,因为强制转换引用永远不会影响指向的对象的状态。如果引用指向的对象尚未是
A
的实例,则强制转换将抛出ClassCastException
。如果强制转换成功,那么这意味着引用指向的对象已经是A
的实例,而您只是用不同类型的引用指向同一对象。你永远不会得到一个有石膏的“新物体”