【问题标题】:Java : casting in clone() methodJava:在 clone() 方法中进行强制转换
【发布时间】:2011-10-16 22:15:06
【问题描述】:

上周在我们的 java 课程中,我们介绍了 Object 类及其一些方法 其中一种方法是 clone(),当我们的老师向我们解释这种方法时,我们被告知 每次我们克隆一个对象时,我们都必须通过 clone() 向下转换返回的对象 因为 clone() 返回一个 Object 类型的对象。

因此,当此方法可以使用 getClass() 之类的另一种方法轻松获取克隆对象的类型时,我找不到为什么该方法更喜欢返回通用对象的原因 并自动处理下铸。

哦,顺便说一句,这不是家庭作业,只是我个人的好奇心让我问了这个问题(我的老师可以给我一个准确的答案,所以我决定暂时让他去做:D)

【问题讨论】:

    标签: java


    【解决方案1】:

    这是因为 clone() 的 java.lang.Object 基类签名返回 Object。您可以在子类方法上覆盖返回的类型,但无论如何这并不是必需的。由于您已经知道要克隆的类,因此可以简单地将其转换为要克隆的类,一切都会好起来的。

    重读您的问题,我注意到您问为什么它不只是获取克隆对象的类型并自动处理向下转换。在内部,它已经在这样做了。更多的是clone() 正在返回一个特定对象,该对象已被向上转换为Object,所有Java 对象都从该对象继承。但是,编译器不会更改您分配给 clone() 的返回值的变量的类型。

    既然你已经知道你要学习的课程,那么你没有任何理由不能自己施法。

    【讨论】:

    • 我现在明白了,所以这只是一种避免像你之前描述的那种奇怪情况的方法:)
    • Java 为被覆盖的方法提供协变返回类型,因此您确实可以用更具体的 clone 类型覆盖返回类型。此外,在您的示例中,someObject.clone() 返回(静态)类型 A 的东西没有问题,就像 A.clone() 被覆盖以声明更具体的类型一样。
    • @MathiasSchwarz 关于someObject.clone() 示例,我意识到这一点,但我想保持答案简单,因为这是一个“家庭作业”问题。显然返回的B 可以相当合理地转换为A - 但它也可以相当合理地转换为Object。至于协方差,根据我的经验,如果您尝试覆盖返回类型,Java 编译器会发出警告(如果不是完全错误);无论如何,它肯定会在clone() 上做到这一点。
    • 没有编译器警告,也没有理由会有。
    • @MathiasSchwarz 哦,你是对的,我刚刚写了一个简单的测试应用程序,它很好。我会相应地编辑我的答案。谢谢。
    【解决方案2】:

    Java 是经过多次修改和稍微奇怪的设计选择的结果。出于某种原因,Java 的设计者决定 clone 总是返回 Object 类型的东西,而正如你自己指出的那样,如果在类 A 上调用该方法,getClass 方法总是返回 Class<? extends A> 类型的东西。

    Java 的协变返回类型允许您覆盖 clone 以获得正确的返回类型,但标准做法是忍受这个缺点并在调用 clone 之后强制转换对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-02
      • 1970-01-01
      • 1970-01-01
      • 2010-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多