【问题标题】:Why does Short.valueOf(n) need a cast为什么 Short.valueOf(n) 需要演员表
【发布时间】:2014-12-02 23:16:14
【问题描述】:

根据this answer,int 常量被隐式转换为short 类型。

但在我的单元测试中,我想测试一个返回 Short 的 getValue() 函数。

assertEquals(obj.getValue(), 42); 

显然上面的行不通,所以我尝试使用 Short.valueOf

assertEquals(obj.getValue(), Short.valueOf(42)); 

然而,这仍然抱怨 - 尽管前面提到了隐式转换 - 所以我必须转换文字。

assertEquals(obj.getValue(), Short.valueOf((short)42)); 

Short.valueOf((short)5) 看起来有点乱!有没有更清洁的方法? (new Short("42") 同样可怕!)

【问题讨论】:

标签: java casting


【解决方案1】:

这是因为将数字从 int 转换为 short 可能会失败(溢出),因为它是 narrowing primitive conversion。理论上,编译器可以识别出参数是一个常量表达式,并且可以在编译时确定转换是否有效。但事实并非如此。

更简洁的方法是:

Short s = 42; //autoboxing is done here
assertEquals(obj.getValue(), s );

上述工作的原因是rules for variable assignment 不同。这里编译器确实会检查常量表达式是否可以转换为short而不会溢出。

此外,如果表达式是类型的常量表达式(第 15.28 节) byte、short、char 或 int:

如果类型为 变量是 byte、short 或 char,以及常量的值 表达式可以用变量的类型来表示。

缩小原始转换后跟装箱转换可能 如果变量的类型是:

字节和常量表达式的值在 输入字节。

短且常量表达式的值可以在 输入短。

字符和常量表达式的值可以表示为 字符类型。

这里适用粗体字。

【讨论】:

    【解决方案2】:

    Short 类中没有以int 为参数的方法,所以

    Short.valueOf(1); // compilation error
    

    但投射到(short) 1

    Short.valueOf((short) 1);
    

    之所以有效,是因为有一种方法可以将 short 作为参数。为什么那个编译器不能为你自动转换,因为

    缩小原语转换可能会丢失有关 数值的整体大小,也可能会丢失精度和 范围。

    【讨论】:

      【解决方案3】:

      其他答案解释了您遇到此问题的原因。更简洁的代码选项可能是:

      assertEquals(obj.getValue().intValue(), 42); 
      

      虽然作为biziclop points out,但如果getValue() 返回null,则会抛出NullPointerException。虽然这仍然会使您的测试失败,但问题出在哪里并不那么明显。

      当然,如果不允许空值,您应该返回short 而不是Short。在这种情况下,您不需要任何演员表:

      assertEquals(obj.getValue(), 42); // fine, if getValue() returns a short
      

      【讨论】:

      • 那会抛出一个 NPE 是 obj.getValue()null
      • @biziclop 好点,那并不理想。虽然测试仍然会失败:-)
      【解决方案4】:

      JLS states

      如果整数文字以 ASCII 字母 L 或 l (ell) 为后缀,则它是 long 类型;否则它是 int 类型(§4.2.1)。

      因此您需要将其转换为short

      也许你也对Why are there no byte or short literals in Java?感兴趣

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-08-03
        • 1970-01-01
        • 2013-01-30
        • 1970-01-01
        相关资源
        最近更新 更多