java - Java cast 运算符如何工作?

标签 java casting jvm

我正在尝试调试涉及 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 (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.

现在完全清楚了,不是吗? :D

换句话说,这是我在不知道有关您的问题的更多细节的情况下所能做的最好的事情。

关于java - Java cast 运算符如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/840322/

相关文章:

c++ - C++ 中的 dynamic_cast 和 static_cast

c++ - static_cast 一个 void* 指针可以吗

java - Kotlin 中的每个类都扩展任何类吗

java - 如何使用嵌入式 ElasticSearch 进行集成测试

java - Apache 点燃: Serialization error related to Data Streaming

javascript - 如何在 JavaScript 中将字符串转换为 float 而不需要 parseFloat 或转换?

java - 私有(private)和公共(public) Java 访问修饰符基础知识

java - 已接受 XX :UseSSE values for Java JVM?

java - Java 版本之间是否存在向后不兼容的具体示例?

Java 应用程序不通过 Finder 中的 .apps 启动