为什么需要多种类型转换?

时间:2015-06-24 16:56:20

标签: java casting

考虑以下层次结构:

TopClass
      |__ MiddleClass
                  |__ BottomClass 

然后,以下代码当然不是必需的:

public BottomClass getBottom() {
    return (BottomClass) (MiddleClass) getObject();
}

getObject()返回BottomClass类型的实例,但返回类型为TopClass

你可以有效地将其短路,并直接投射到BottomClass

但是这段代码引起了我的注意:

在JavaFX源包中, class:com.sun.javafx.scene.control.skin.ProgressIndicatorSkin

@Override
public StyleableProperty<Paint> getStyleableProperty(ProgressIndicator n) {
    final ProgressIndicatorSkin skin = (ProgressIndicatorSkin) n.getSkin();
        return (StyleableProperty<Paint>)(WritableValue<Paint>)skin.progressColor;
}

接口层次结构为:

WritableValue<T>
              |__ StyleableProperty<T>

progressColor类型为StyleableObjectProperty<Paint>,实现StyleableProperty<Paint>,但存储在ObjectProperty<Paint>变量中,如下所示:

private ObjectProperty<Paint> progressColor = new StyleableObjectProperty<Paint>(null)

有什么线索在这里发生了什么?

1 个答案:

答案 0 :(得分:1)

中间演员似乎没必要。直接投射应该有效。

然而,直接演员将是两种类型之间没有明显亚型关系的“交叉”演员阵容。

程序员可能不希望这样;相反,程序员向最近的普通超类型转换更为舒适,然后做一个感觉“更安全”的向下转换。

对演员表的讨论:

进行“向上”投射总是安全的

    (Animal)cat

允许进行“向下”演员表演;编译器假定程序员更了解实际的运行时类型

    (Cat)animal

这是一个问题的“交叉”演员。有时很明显,交叉投射是不可能的

    (Cat)dog   // Cat and Dog are two classes, and no subclass relation

    (List<Cat>) listDog   //  List<Dog> => List<Cat>

    (Runnable)fish    // Fish is a final class that does not implement Runnable

但是,如果可证明不正确,编译器会允许它,信任程序员

     (Runnable)animal   // Animal class does not implement Runnable; but a subclass may

我们总是可以通过常见的超类型

来强制转换
     (List<Cat>)(List<?>) listDog

当然,Object是所有类型的常见超类型,因此我们可以使用它强制任何类型转换

     (Cat)(Object)dog