在java中强制转换clone()
因此,我的书中有以下内容:在java中强制转换clone(),java,calendar,clone,Java,Calendar,Clone,因此,我的书中有以下内容: Calendar calendar = new GregorianCalendar(2013,2,1); Calendar calendar1 = (Calendar)calendar.clone(); 为什么需要铸造(日历)?calendar.clone()不是正在返回calendar的副本吗?如果我删除强制转换,这是一个编译错误,但是如果我写入System.out.println(calendar.clone().getClass())它打印GregoriaCa
Calendar calendar = new GregorianCalendar(2013,2,1);
Calendar calendar1 = (Calendar)calendar.clone();
为什么需要铸造(日历)
?calendar.clone()
不是正在返回calendar
的副本吗?如果我删除强制转换,这是一个编译错误,但是如果我写入System.out.println(calendar.clone().getClass())代码>它打印GregoriaCalendar
。calendar1
是否在calendar.clone()
(未强制转换)之后指向一个gregoriacalendar
。这就是为什么需要将其强制转换为Calendar
(编译器不知道实际返回的实例的类型是Calendar
)
通常,不能将返回X
的方法的返回值分配给X
的子类变量
/**
* Creates and returns a copy of this object.
*
* @return a copy of this object.
*/
public Object clone() {}
至于它返回对象
的原因,日历
具有重写克隆
方法的子类。因此,它们都必须返回相同的类型。我认为,由于协方差的原因,它们可以使clone
返回单个类型。但是协方差直到后来才被添加到Java中。它不是返回了一个GregoriaCalendar吗?in-System.out.print(calendar.clone().getClass());上面说这是一个Gregorianalendar而不是一个Object@PopTudor方法声明为其返回类型的类型与它在特定方法调用中返回的对象的实际类型(只有在运行时才知道)之间存在差异。编译器只知道前者,不能根据后者做出决定。clone()方法设计的一个缺点是clone()的返回类型是Object,需要显式转换回适当的类型。但是,重写clone()以返回适当的类型更可取,并且无需在客户端强制转换(使用协变返回类型,自J2SE 5.0以来)。关于编译时与运行时类型的一般评论:如果您说MyClass x=something
或public MyClass method()
,变量或函数结果可以是MyClass
或其任何子类,但编译器只允许知道它是MyClass
。因此,如果你说子类y=x
,编译器会拒绝它,因为它不知道x
是否是子类。运行时,x
可能是子类
并不重要。如果您说SubClass y=(SubClass)x
,它将编译,程序将在运行时检查x
是否是子类
@ajb是的,我理解,但这不是我的情况,因为GregorianCalendar是Calendar的子类,如果我执行System.out.print(Calendar.clone().getClass())它说克隆是一个格里高利安日历,日历可以包含对格里高利安日历的引用;如果我写calendar1=(GregorianCalendar)Calendar.clone();它仍然是一个有效的表达式,我没有得到任何错误。那么为什么要显式强制转换呢?@PopTudor您在getClass()
中看到的是运行时类型。运行时类型对编译器并不重要,因为它无法预测运行时类型。据它所知,clone()
的结果是一个对象。当您运行它时,它是gregoriacalendar
,这一事实对编译器来说根本不重要。您可以将calendar1=
指定为GregorianCalendar
,因为所有GregorianCalendar
s都是Calendar
s。但并非所有的对象
s都是日历
s。