为什么Short.valueOf(n)需要强制转换

时间:2014-10-08 10:17:22

标签: java casting

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

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

assertEquals(obj.getValue(), 42); 

显然上面没有用,所以我尝试使用Short.valueOf

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

然而,这仍然抱怨 - 尽管有上述隐含的转换 - 所以我必须施展文字。

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

Short.valueOf((短)5)似乎有点乱!有更干净的方式吗? (新短片(" 42")同样可怕!)

4 个答案:

答案 0 :(得分:8)

这是因为将数字从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,以及常量的值   表达式可以在变量的类型中表示。

     

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

,则使用      

字节和常量表达式的值可表示为   输入byte。

     

短,常量表达式的值可表示为   类型简短。

     

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

粗体情况适用于此。

答案 1 :(得分:1)

其他答案解释了为什么你有这个问题。代码的清洁选项可能是:

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

虽然为biziclop points out,但如果getValue()返回null,则会抛出NullPointerException。虽然这仍然无法通过测试,但出现问题的方法并不是那么明显。

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

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

答案 2 :(得分:1)

Short class中没有方法将int作为参数,所以

Short.valueOf(1); // compilation error

但是要转换为(short) 1

Short.valueOf((short) 1);

有效,因为有一个方法将short作为参数。为什么该编译器不能自动为您进行转换,因为

  

缩小的原始转换可能会丢失有关的信息   数值的整体幅度,也可能失去精度   范围。

答案 3 :(得分:0)

JLS states

  

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

因此您需要将其投射到short

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

感兴趣