2014-10-08 69 views
3

根据this answer,int常量会隐式转换为短型。为什么Short.valueOf(n)需要铸造

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

assertEquals(obj.getValue(), 42); 

显然,上述不工作,所以我尝试使用Short.valueOf

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

但是,这仍然抱怨 - 尽管上述隐式转换 - 所以我必须要投的文字。

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

Short.valueOf((short)5)似乎有点凌乱!有更清洁的方法吗? (新短( “42”)同样恐怖!)

+1

它需要一个强制转换,因为**字符整数**值被视为“int”,所以您需要告诉编译器它实际上是一个“short”。 – 2014-10-08 10:19:20

+0

与此相关:http://stackoverflow.com/questions/317816/why-are-there-no-byte-or-short-literals-in-java – PeterMmm 2014-10-08 10:19:57

+0

看看JLS中的Integer Literals:http:/ /docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.1 – 2014-10-08 10:21:24

回答

8

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

一个清洁的方法是:

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

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

此外,如果表达式是 类型字节,短,炭或int的常量表达式(§15.28):

甲基本收缩转换可以如果 变量的类型使用是字节,短或字符,并且常量 表达式的值可用变量的类型表示。

字节和常量表达式的值在 类型字节可表示:

甲基本收缩转换接着装箱转换如果变量的类型是可以 可以使用。

短而且常量表达式的值可在 类型short中表示。

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

黑体案适用于此处。

1

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

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

虽然作为biziclop points out,这将抛出一个NullPointerException如果getValue()返回null。尽管这样做仍然会使你的测试失败,但是出错的地方并不是那么明显。

当然,如果不允许空值,您应该返回short而不是Short。在这种情况下,你不需要任何强制转换:

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

这会抛出一个NPE是'obj.getValue()'是'null' – biziclop 2014-10-08 10:26:32

+1

@biziclop好点,那不会是理想的。虽然测试仍然会失败:-) – 2014-10-08 10:27:37

1

有短篇小说类没有方法来获取int作为参数,则使

Short.valueOf(1); // compilation error 

但铸造(short) 1

Short.valueOf((short) 1); 

工作,因为有一种方法,作为参数短。这是为什么编译器不能做自动浇注你,因为

的基本收缩转换可能会失去约数值的 整体幅度信息,并且还可能会丢失精度和 范围。