java – 数字文字的自动装箱:包装器初始化与传递方法参数不一致

请考虑2个案例:

//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中那样尝试应用自动装箱,那么为什么呢?

编辑

johnchen902中对JSL的引用解释了编译器的行为.

仍然不完全清楚为什么JLS不支持方法调用转换的“缩小原始转换后跟装箱转换”,因为它在分配转换中为byte,short,char或int类型的常量表达式的情况.
有任何想法吗 ?

解决方法:

Short s = 10;

这是一个赋值转换,10是一个常量表达式. JLS说:

5.2. Assignment Conversion

Assignment conversion occurs when the value of an expression is assigned to a variable: the type of the expression must be converted to the type of the variable.

……

In addition, if the expression is a constant expression of type byte, short, char, or int:

  • A narrowing primitive conversion followed by a boxing conversion may be used if the type of the variable is:
    • Short and the value of the constant expression is representable in the type short.
takeShort(10);

这是一个方法调用转换. JLS说:

5.3. Method Invocation Conversion

Method invocation conversion is applied to each argument value in a method or constructor invocation : the type of the argument expression must be converted to the type of the corresponding parameter.

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.

……

If the type of the expression cannot be converted to the type of the parameter by a conversion permitted in a method invocation context, then a compile-time error occurs.

与分配转换不同,上面列出的非转换可以将int转换为Short,因此发生编译时错误.

不幸的是,在我批准之前,有些人拒绝了kiruwka的编辑,因此我自己编辑

Method调用转换的示例:

// 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.
上一篇:没有默认ctor的C私有变量-无法编译?


下一篇:如何使用新的OpenSSL库编译PHP