Java - 简短和铸造

时间:2010-04-27 11:34:40

标签: java casting primitive-types

我有以下代码段。

public static void main(String[] args) {
 short a = 4;
 short b = 5;
 short c = 5 + 4;
 short d = a;
 short e = a + b; // does not compile (expression treated as int)


 short z = 32767;
 short z_ = 32768; // does not compile (out of range)

 test(a);
 test(7); // does not compile (not applicable for arg int)
}

public static void test(short x) { }

以下摘要是否正确(仅针对上述示例使用简短)?

  • 无需强制转换的直接初始化只能使用文字或单个变量(只要该值在声明的类型范围内)
  • 如果赋值的rhs使用变量处理表达式,则必须进行强制转换

但是为什么我需要在考虑前面的摘要的情况下转换第二个方法调用的参数?

3 个答案:

答案 0 :(得分:18)

这些是相关的JLS部分:

JLS 5.1.1 Identity Conversion

  

任何类型都允许从类型转换为相同类型。

JLS 5.2 Assignment Conversion

  

当将表达式的值赋给变量时,会发生赋值转换:必须将表达式的类型转换为变量的类型。分配上下文允许使用以下之一:

     
      
  • 身份转换
  •   
  • [...]
  •   
     

此外,如果表达式是byteshortcharint类型的常量表达式:

     
      
  • 如果变量的类型是byteshortchar,则可以使用缩小的基元转换,并且常量表达式的值可以在类型中表示。变量
  •   

以上规则解释了以下所有内容:

short a = 4;     // representable constant
short b = 5;     // representable constant
short c = 5 + 4; // representable constant
short d = a;     // identity conversion
short e = a + b; // DOES NOT COMPILE! Result of addition is int

short z  = 32767; // representable constant
short z_ = 32768; // DOES NOT COMPILE! Unrepresentable constant

至于为什么不编译:

test(7); // DOES NOT COMPILE! There's no test(int) method!

这是因为使用常量缩小转换仅为分配定义;不适用于具有完全不同规则的方法调用。

JLS 5.3. Method Invocation Conversion

  

方法调用转换特别不包括作为赋值转换一部分的整数常量的隐式缩小。 Java编程语言的设计者认为,包含这些隐式缩小转换将为重载方法匹配解析过程增加额外的复杂性。

我将引用 Effective Java 2nd Edition ,而不是解释方法解析如何正确工作,第41项:明智地使用重载:

  

确定选择哪个重载的规则非常复杂。他们在语言规范中占用三十三个页面,很少有程序员理解他们的所有细微之处。


另见

答案 1 :(得分:1)

short值的算术运算结果始终为inttest(7)不起作用,因为您没有说7是short类型。编译器在这里应该更聪明一点。

答案 2 :(得分:1)

来电test(7);中的'7'为int,不会自动转换为short

当您声明并初始化short值时,它会起作用,但这是编译器的特例。方法调用不存在这种特殊情况。