问题描述
请考虑2种情况:
//1
Short s = 10; //obviously compiles
//2
takeShort(10); //error - int is not applicable
//where:
static void takeShort(Short s) {}
我假设case 1被编译器改成:
I assume that case 1 is changed by compiler to :
short _temp_s = 10;
Short s = Short.valueOf(_temp_s);
你能解释一下编译器在case 2中要做什么,如果不是像在案例1中那样尝试应用自动装箱,那么为什么?
Could you please explain what compiler is trying to do in case 2, so it does not compile ? If it is not trying to apply autoboxing as it does in case 1, then why ?
EDIT
参考johnchen902中的JSL回答解释了编译器的行为。
Reference to JSL in johnchen902 answer explains compiler's behaviour.
仍然不完全清楚为什么JLS不支持缩小原语转换后加拳击转换对于类型为byte,short,char或int的常量表达式的情况下,方法调用转换与分配转换中的方法调用转换类似。
任何想法?
Still not exactly clear why JLS does not support "A narrowing primitive conversion followed by a boxing conversion" for Method Invocation Conversion as it does in Assignment Conversion for the case of constant expression of type byte, short, char, or int.Any ideas ?
推荐答案
Short s = 10;
这是一个分配转换
code> 10 是一个常量表达式。 说:
This is an Assignment Conversion
, and 10
is a constant expression. JLS said:
......
此外,如果表达式是一个常量表达式byte,short,char ,或int:
In addition, if the expression is a constant expression of type byte, short, char, or int:
- 如果变量的类型是:
-
- 短和常量表达式的值可以在类型short中表示。
$ b btakeShort(10);
这是一个
方法调用转换
。 说:方法调用上下文允许使用以下方法之一:
Method invocation contexts allow the use of one of the following:
- 身份转换
- 加宽的原始转换
- 加宽参考转换
- 参考转换
- 一个取消装箱的转换,可选地后面是一个加宽的原始转换。
- an identity conversion
- a widening primitive conversion
- a widening reference conversion
- a boxing conversion optionally followed by widening reference conversion
- an unboxing conversion optionally followed by a widening primitive conversion.
... ...
如果表达式的类型不能通过方法调用上下文中允许的转换转换为参数的类型,
与分配转换不同,上面列出的非转换可以转换
int
到Short
,因此发生编译时错误。Unlike Assignment Conversion, non of conversion listed above can converts
int
toShort
, so a compile-time error occurs.方法调用转换的示例:
// 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.
这篇关于数字文字自动装箱:包装器初始化vs传递方法参数不一致的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!