问题描述
我正在尝试调试一个涉及 Java 中 ClassCastException 的问题.为了解决这个问题,我需要知道当我从 Object 转换为特定类型时发生了什么.谁能向我解释 Java 强制转换运算符如何在 Java 级别和 JVM 级别工作?
I am trying to debug an issue involving a ClassCastException in Java. In the interest of solving the issue I need to know what is going on when I cast from Object to a specific type. Can anyone explain to me how the Java cast operator works at the Java level and the JVM level?
推荐答案
是 JLS够好吗?
强制转换应用于强制转换运算符的操作数(第 15.16 节):必须将操作数表达式的类型转换为强制转换运算符显式命名的类型.铸造上下文允许使用:
- 身份转换(第 5.1.1 节)
- 扩大原始转换(第 5.1.2 节)
- 缩小原始转换(第 5.1.3 节)
- 加宽参考转换(第 5.1.5 节),可选后跟未经检查的转换(第 5.1.9 节)
- 窄化引用转换(第 5.1.6 节),可选后跟未经检查的转换
- 拳击转换(第 5.1.7 节)
- 拆箱转换(第 5.1.8 节).
实际上,也许这部分 更相关:
Actually, maybe this part is more relevant:
将编译时引用类型S的值强制转换为编译时引用类型T的编译时合法性的详细规则如下:
- 如果S 是一个类类型:
- 如果 T 是一个类类型,然后是 |S|<: |T|,或 |T|<:|S|;否则编译时发生错误.此外,如果有存在一个超类型 XT 和一个超类型 YS,使得 X 和Y 可证明是不同的参数化类型(第 4.5 节),以及 X 的擦除和Y 都是一样的,编译时发生错误.
- 如果 T 是接口类型:
- 如果S 不是
final
类(第 8.1.1 节),那么,如果存在超类型T 的 X 和一个超类型S 的 Y,使得两者X 和 Y 是可证明的不同的参数化类型,并且X 和 Y 的擦除都一样,编译时错误发生.否则,演员表总是在编译时合法(因为即使S 没有实现 T,S 的子类可能). - 如果 S 是一个
final
类(第 8.1.1 节),那么 S 必须实现 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.
- 如果S 不是
- 如果T是一个类型变量,那么这个算法被递归地应用,使用 T 的上限T 的位置.
- 如果 T 是一个数组类型,那么 S 必须是类
Object
,或发生编译时错误. - 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.- 如果 T 是一个数组类型,那么 T 必须实现 S,或编译时发生错误.
- 如果 T 是不属于
final
(第 8.1.1 节),那么如果存在超类型T 的 X 和一个超类型S 的 Y,使得两者X 和 Y 是可证明的不同的参数化类型,并且X 和 Y 的擦除都一样,编译时错误发生.否则,演员表总是在编译时合法(因为即使T 没有实现 S,T 的子类可能). - 如果 T 是
final
类型,然后:- 如果 S 不是参数化的类型或原始类型,则 T 必须实现 S,并且演员表是静态已知是正确的,或发生编译时错误.
- 否则,S 要么是参数化的调用某些类型的类型泛型类型声明 G,或对应于泛型的原始类型类型声明 G.然后有必须存在一个超类型 XT,使得 X 是一个G 的调用,或发生编译时错误.此外,如果 S 和 X可证明是不同的参数化然后键入编译时错误发生.
- 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.
- 如果 T 是一个类类型,则如果 T 不是
Object
,然后一个发生编译时错误(因为Object
是唯一的类可以分配数组的类型). - 如果T是一个接口类型,那么一个除非发生编译时错误T 是类型
java.io.Serializable
或Cloneable
类型,仅由数组实现的接口. - 如果T是类型变量,则:
- 如果上T 的边界是
Object
或类型java.io.Serializable
或Cloneable
类型,或S 可以输入的类型变量合法地被递归强制转换应用这些规则,那么演员表是合法(虽然未经检查). - 如果上T 的边界是数组类型TC[],然后是编译时错误除非类型 SC[] 可以通过递归转换为 TC[] 应用这些编译时铸造规则.
- 否则,a发生编译时错误.
- 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.
现在完全清楚了,不是吗?:D
Perfectly clear now, isn't it? :D
换句话说,这是我在不了解您的问题的更多细节的情况下所能做的最好的事情.
In other words, this is the best I can do without knowing more details about your problem.
这篇关于Java 强制转换运算符是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
- If the upper bound of T is
- 如果上T 的边界是