Reputation: 16284
Consider the following hierarchy:
TopClass
|__ MiddleClass
|__ BottomClass
Then the following code is of-course not required:
public BottomClass getBottom() {
return (BottomClass) (MiddleClass) getObject();
}
Where getObject()
returns an instance of type BottomClass
but has a return type of TopClass
.
You could effectivily short-circuit it, and cast directly to BottomClass
.
But this code raised my brows:
In the JavaFX source package,
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;
}
Where the interface hierarchy is:
WritableValue<T>
|__ StyleableProperty<T>
And progressColor
is of type StyleableObjectProperty<Paint>
, that implements StyleableProperty<Paint>
, but is stored in an ObjectProperty<Paint>
variable, like this:
private ObjectProperty<Paint> progressColor = new StyleableObjectProperty<Paint>(null)
Any clue what's going on here?
Upvotes: 1
Views: 154
Reputation: 19682
The intermediary cast seems unnecessary. Direct cast should work.
However, the direct cast would be a "cross" cast - casting between two types that has no apparent subtype relationship.
The programmer probably doesn't want that; instead, it's more comfortable for the programmer to upcast to a nearest common supertype, then do a downcast, which feels "safer".
Discussion of casts:
It's always safe to do an "up" cast
(Animal)cat
It is allowed to do a "down" cast; the compiler assumes the programmer knows better about the actual runtime type
(Cat)animal
It is the "cross" cast that is a problem. Sometimes it is obvious that the cross-cast is impossible
(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
However, if it is not provably incorrect, the compiler would allow it, trusting the programmer
(Runnable)animal // Animal class does not implement Runnable; but a subclass may
We can always cast between any two types by going through a common supertype
(List<Cat>)(List<?>) listDog
Of course, Object is the common supertype of all types, so we can use it to force any casts
(Cat)(Object)dog
Upvotes: 1