考虑以下层次结构:
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)
有什么线索在这里发生了什么?
答案 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