Java 强制转换运算符是如何工作的? [英] How does the Java cast operator work?

查看:19
本文介绍了Java 强制转换运算符是如何工作的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试调试一个涉及 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 节):必须将操作数表达式的类型转换为强制转换运算符显式命名的类型.铸造上下文允许使用:

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:

  • 身份转换(第 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,使得 XY 可证明是不同的参数化类型(第 4.5 节),以及 X 的擦除和Y 都是一样的,编译时发生错误.
    • 如果 T 是接口类型:

      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:
      • 如果S 不是 final类(第 8.1.1 节),那么,如果存在超类型TX 和一个超类型SY,使得两者XY 是可证明的不同的参数化类型,并且XY 的擦除都一样,编译时错误发生.否则,演员表总是在编译时合法(因为即使S 没有实现 TS 的子类可能).
      • 如果 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.

    • 如果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 节),那么如果存在超类型TX 和一个超类型SY,使得两者XY 是可证明的不同的参数化类型,并且XY 的擦除都一样,编译时错误发生.否则,演员表总是在编译时合法(因为即使T 没有实现 ST 的子类可能).
      • 如果 Tfinal 类型,然后:
        • 如果 S 不是参数化的类型或原始类型,则 T 必须实现 S,并且演员表是静态已知是正确的,或发生编译时错误.
        • 否则,S 要么是参数化的调用某些类型的类型泛型类型声明 G,或对应于泛型的原始类型类型声明 G.然后有必须存在一个超类型 XT,使得 X 是一个G 的调用,或发生编译时错误.此外,如果 SX可证明是不同的参数化然后键入编译时错误发生.
        • 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.SerializableCloneable 类型,仅由数组实现的接口.
          • 如果T是类型变量,则:
            • 如果上T 的边界是Object 或类型java.io.SerializableCloneable 类型,或S 可以输入的类型变量合法地被递归强制转换应用这些规则,那么演员表是合法(虽然未经检查).
            • 如果上T 的边界是数组类型TC[],然后是编译时错误除非类型 SC[] 可以通过递归转换为 TC[] 应用这些编译时铸造规则.
            • 否则,a发生编译时错误.
            • 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.

              现在完全清楚了,不是吗?: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 强制转换运算符是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆