Is the JLS good enough?
Casting conversion is applied to the operand of a cast operator (§15.16): the type of the operand expression must be converted to the type explicitly named by the cast operator. Casting contexts allow the use of:
- an identity conversion (§5.1.1)
- a widening primitive conversion (§5.1.2)
- a narrowing primitive conversion (§5.1.3)
- a widening reference conversion (§5.1.5) optionally followed by an unchecked conversion (§5.1.9)
- a narrowing reference conversion (§5.1.6) optionally followed by an unchecked conversion
- a boxing conversion (§5.1.7)
- an unboxing conversion (§5.1.8).
Actually, maybe this part is more relevant:
The detailed rules for compile-time legality of a casting conversion of a value of compile-time reference type S to a compile-time reference type T are as follows:
- 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.
- If T is an interface type:
- 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.
- If T is
an array type, then S must be
the class
Object
, or a
compile-time error occurs.
- If S is
an interface type:
- If T is
an array type, then T must
implement S, 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, and the cast is
statically known to be correct, 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 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 (because
Object
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 type Cloneable
, the
only interfaces implemented by arrays.
- If T
is a type variable, then:
- If the upper
bound of T is
Object
or the type
java.io.Serializable
or
the type Cloneable
, or a
type variable that S could
legally be cast to by recursively
applying these rules, 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
be cast to TC[] by a recursive
application of these compile-time
rules for casting.
- Otherwise, a
compile-time error occurs.
- 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:
- TC and SC are the
same primitive type.
- TC and
SC are reference types and type
SC can be cast to TC by
a recursive application of these
compile-time rules for casting.
Perfectly clear now, isn't it? :D
In other words, this is the best I can do without knowing more details about your problem.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…