【问题标题】:Java: Widening and autoboxing conversion issueJava:扩大和自动装箱转换问题
【发布时间】:2013-07-29 22:40:56
【问题描述】:

我不明白为什么 java 不进行扩展然后自动装箱。

Integer i = (short) 10;

我认为会发生以下情况:

  1. 首先将转换范围从10 缩小到short
  2. 然后short 会扩大到int
  3. 然后int 会自动装箱到Integer

反而是编译错误。

示例 2:

短 x = 10;
整数 y = x;

这也失败了。

【问题讨论】:

    标签: java type-conversion


    【解决方案1】:

    根据JLS, Section 5.2,它处理赋值转换

    分配上下文允许使用以下之一:

    • 身份转换 (§5.1.1)

    • 加宽基元转换 (§5.1.2)

    • 扩大参考转换 (§5.1.5)

    • 一个装箱转换(第 5.1.7 节)可选地后跟一个加宽 参考转化

    • 一个拆箱转换 (§5.1.8) 可选地后跟一个加宽 原始转换。

    不能同时应用两个转换(加宽原始转换和装箱转换);此处只能应用一次转换,因此必须导致错误。

    解决方案是将short 强制转换回int(强制转换),这将允许赋值转换成为装箱转换:

    Integer i = (int) (short) 10;
    

    (或者在这里,首先不要将其转换为short。)

    Integer i = 10;
    

    【讨论】:

    • 基于 JLS 5.1.5,为什么我的示例 2 失败了?
    • 在处理诸如ShortInteger 之类的包装对象时,重要的是要认识到Short 不是 Integer;一个不子类化另一个。您在此处引用的转换(扩大引用转换)在此处不适用。
    • 哦,是的。我现在想起了。扩大参考转换涉及子类 - 换句话说,相关的类。谢谢
    【解决方案2】:

    这里发生的是从intshort 的强制转换,然后是从shortInteger 的尝试赋值转换。

    分配转换 (§5.2) 允许先装箱然后加宽,但不允许先加宽然后装箱。

    分配上下文允许使用以下之一:

    • 身份转换 (§5.1.1)

    • 加宽基元转换 (§5.1.2)

    • 扩大参考转换 (§5.1.5)

    • 一个装箱转换(第 5.1.7 节)可选地后跟一个加宽 参考转化

    • 一个拆箱转换 (§5.1.8) 可选地后跟一个加宽 原始转换。

    【讨论】:

    • 为什么不将 int 转为 short 然后转为 int 再转为 Integer?不够聪明? :OP
    • @yapkm01 不是JVM不够智能,而是根本不允许。 shortint 是扩大的原始转换,intInteger 是装箱转换。赋值转换只能执行这两个操作之一,不能同时执行。
    【解决方案3】:

    在 java 中,无论您是否在做,它都遵循“自动装箱然后加宽”的顺序 这 : 整数 x =5; 对象 obj = x;

    或者 这个:

    int x = 5; 长 l = x;

    仅当存在 is-a 关系时才会发生扩展。
    因此,虽然应用上述序列的第一种情况对编译器非常有效,因为 int 将自动装箱为 Integer,然后分配给 Object,即加宽(即先自动装箱,然后加宽),处于 Is-A 关系。但是在第二种情况下,如果 int x 是 autbox 到 Integer 并且分配给 Long 则不允许,因为不是 is-a 关系,因此会引发编译错误。

    【讨论】:

      【解决方案4】:

      可以在自动装箱和扩展方面使用重载来模拟类似的用例。

      public static void m(short s) {
          System.out.println("widening");
        }
      
      public static void m(Integer i) {
          System.out.println("Autoboxing");
      }
      
      public static void main(String[] args) {
          short x = 10;
          m(x);
      }
      

      输出:加宽

      因此,简而言之,我们可以说,Java 中的自动装箱占主导地位

      【讨论】:

        猜你喜欢
        • 2018-06-20
        • 1970-01-01
        • 2023-04-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-02
        • 1970-01-01
        • 2010-09-05
        相关资源
        最近更新 更多