请考虑两种情况:
//1
Short s = 10; //obviously compiles
//2
takeShort(10); //error - int is not applicable
//where:
static void takeShort(Short s) {}
我认为这种情况下,1是由编译器更改为:
short _temp_s = 10;
Short s = Short.valueOf(_temp_s);
能否请您解释一下编译器试图在2的情况下做的,所以它不编译? 如果不尝试应用的情况下,自动装箱1如确实如此,那么为什么呢?
编辑
参考JSL在johnchen902回答解释了编译器的行为。
仍然不完全清楚为什么JLS不支持“A基本收缩转换接着装箱转换”为方法调用转换,因为它在赋值转换确实为类型字节,短,炭或int的恒定表达的情况下。 有任何想法吗 ?
Short s = 10;
这是一个Assignment Conversion
,和10
是一常量表达式。 JLS说:
5.2。 赋值转换
当表达式的值被分配给一个变量出现赋值转换:表达式的类型必须被转换到可变的类型。
......
此外,如果表达式的类型是字节,短,炭或int的常量表达式:
takeShort(10);
这是一个Method Invocation Conversion
。 JLS说:
5.3。 方法调用转换
方法调用转换应用于每个参数值的方法或构造函数调用:参数表达式的类型必须被转换成相应的参数的类型。
方法调用上下文允许使用下列之一:
- 身份转换
- 加宽原语转换
- 加宽引用转换
- 装箱转换任选地随后通过加宽引用转换
- 取消装箱转换任选接着进行加宽原语转换。
......
如果表达式的类型不能由一个方法调用上下文所允许的转换被转换成参数的类型,则发生编译时间错误。
不同于赋值转换,上面列出的转化非可转换int
到Short
,所以发生编译时间错误。
不幸的是一些已经拒绝kiruwka的编辑之前,我可以批准它,所以我编辑它自己
方法调用转换的例子:
// takeInteger(int) takeDouble(double) takeObject(Object) takeIntegerObject(Integer)
takeInteger(5); // an identity conversion
takeDouble(5); // a widening primitive conversion
takeObject(new Integer(5)); // a widening reference conversion
takeIntegerObject(5); // a boxing conversion
takeObject(5); // a boxing conversion followed by widening reference conversion
takeInteger(new Integer(5)); // an unboxing conversion
takeDouble(new Integer(5)); // an unboxing conversion followed by a widening primitive conversion.
喜欢的文字10
是int
默认情况下,在Java中。 所以,你要转让int
,其采用的方法Short
或short
作为参数,这需要显式类型转换。 您可以分配10
到short
变量,但你不能将它作为参数传递给接受的方法Short
或short
。 你可以施放它,并将它传递如下:
takeShort((short)10);
编辑:
的int
的范围为-2147483648
到2147483647
,而short
的范围为-32768
到32767
。 除非到文字的值的范围之内short
,它会好起来的编译器将其转换为short
。 但是,正如鲍里斯蜘蛛在他的评论中提到的,一旦字面值超过范围short
,这将无法字面转换为short
,因为会有数据丢失。 因此,编译器不将文字转换为short
,当如在方法的参数中国率先。
文章来源: autoboxing of numeric literals : wrapper initialization vs passing method arguments inconsistency