我正在尝试调试涉及 Java 中的 ClassCastException 的问题。为了解决这个问题,我需要知道当我从 Object 转换为特定类型时发生了什么。 任何人都可以向我解释一下 Java 强制转换运算符在 Java 级别和 JVM 级别是如何工作的吗?
最佳答案
是 JLS够好了吗?
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).
实际上,也许this part更相关:
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 (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
or the typejava.io.Serializable
or the typeCloneable
, 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.
现在完全清楚了,不是吗? :D
换句话说,这是我在不知道有关您的问题的更多细节的情况下所能做的最好的事情。
关于java - Java cast 运算符如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/840322/