根据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")同样可怕!)
答案 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)
如果整数文字后缀为ASCII字母L或l(ell),则其长度为long;否则它的类型为int(§4.2.1)。
因此您需要将其投射到short
。