5.5.1. Reference Type Casting
Given a compile-time reference type S (source) and a compile-time reference type T (target), a casting conversion exists from S to T if no compile-time errors occur due to the following rules.
If S is a class type:
-
If T is a class type, then either |S|
<:
|T|, or |T|<:
|S|. Otherwise, a compile-time error occurs.Furthermore, if there exists a supertype X of T, and a supertype Y of S, such that both X and Y are provably distinct parameterized types (§4.5), and that the erasures of X and Y are the same, a compile-time error occurs.
package test5;
interface II {}
class XY<T> {}
class T extends XY<Integer>implements II {}
class S extends XY<Number>implements II {}
public class main1 {
public static void main(String args[]) {
II a = new S();
T t = (T) a; // test5.S cannot be cast to test5.T
}
}
-
-
If S is not a
final
class (§8.1.1), then, if there exists a supertype X of T, and a supertype Y of S, such that both X and Y are provably distinct parameterized types, and that the erasures of X and Y are the same, a compile-time error occurs.Otherwise, the cast is always legal at compile time (because even if S does not implement T, a subclass of S might).
-
If S is a
final
class (§8.1.1), then S must implement T, or a compile-time error occurs.
-
-
If T is a type variable, then this algorithm is applied recursively, using the upper bound of T in place of T.
interface I{}
class S implements I {}
public class main2<B extends I,T extends B> {
public void test(){
T d = (T)new S(); // Type safety: Unchecked cast from S to D
}
}
If S is an interface type:
-
If T is an array type, then S must be the type
java.io.Serializable
orCloneable
(the only interfaces implemented by arrays), or a compile-time error occurs. -
If T is a type that is not
final
(§8.1.1), then if there exists a supertype X of T, and a supertype Y of S, such that both X and Y are provably distinct parameterized types, and that the erasures of X and Y are the same, a compile-time error occurs.Otherwise, the cast is always legal at compile time (because even if T does not implement S, a subclass of T might).
-
If T is a type that is
final
, then:-
If S is not a parameterized type or a raw type, then T must implement S, or a compile-time error occurs.
-
Otherwise, S is either a parameterized type that is an invocation of some generic type declaration G, or a raw type corresponding to a generic type declaration G. Then there must exist a supertype X of T, such that X is an invocation of G, or a compile-time error occurs.
Furthermore, if S and X are provably distinct parameterized types then a compile-time error occurs.
-
If S is a type variable,
then this algorithm is applied recursively, using the upper bound of S in place of S.
If S is an intersection type A1 &
... &
An,
then it is a compile-time error if there exists an Ai (1 ≤ i ≤ n) such that S cannot be cast to Ai by this algorithm. That is, the success of the cast is determined by the most restrictive component of the intersection type.
If S is an array type SC[]
, that is, an array of components of type SC:
-
If T is a class type, then if T is not
Object
, then a compile-time error occurs (becauseObject
is the only class type to which arrays can be assigned). -
If T is an interface type, then a compile-time error occurs unless T is the type
java.io.Serializable
or the typeCloneable
(the only interfaces implemented by arrays). -
If T is a type variable, then:
-
If the upper bound of T is
Object
orjava.io.Serializable
orCloneable
, or a type variable that S could undergo casting conversion to, then the cast is legal (though unchecked). -
If the upper bound of T is an array type TC
[]
, then a compile-time error occurs unless the type SC[]
can undergo casting conversion to TC[]
.
-
-
If T is an array type TC
[]
, that is, an array of components of type TC, then a compile-time error occurs unless one of the following is true: