我有以下代码段。
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) { }
以下摘要是否正确(仅针对上述示例使用简短)?
但是为什么我需要在考虑前面的摘要的情况下转换第二个方法调用的参数?
答案 0 :(得分:18)
这些是相关的JLS部分:
任何类型都允许从类型转换为相同类型。
当将表达式的值赋给变量时,会发生赋值转换:必须将表达式的类型转换为变量的类型。分配上下文允许使用以下之一:
- 身份转换
- [...]
此外,如果表达式是
byte
,short
,char
或int
类型的常量表达式:
- 如果变量的类型是
byte
,short
或char
,则可以使用缩小的基元转换,并且常量表达式的值可以在类型中表示。变量
以上规则解释了以下所有内容:
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!
这是因为使用常量缩小转换仅为分配定义;不适用于具有完全不同规则的方法调用。
方法调用转换特别不包括作为赋值转换一部分的整数常量的隐式缩小。 Java编程语言的设计者认为,包含这些隐式缩小转换将为重载方法匹配解析过程增加额外的复杂性。
我将引用 Effective Java 2nd Edition ,而不是解释方法解析如何正确工作,第41项:明智地使用重载:
确定选择哪个重载的规则非常复杂。他们在语言规范中占用三十三个页面,很少有程序员理解他们的所有细微之处。
short x = 3; x += 4.6;
编译答案 1 :(得分:1)
short
值的算术运算结果始终为int
。 test(7)
不起作用,因为您没有说7是short
类型。编译器在这里应该更聪明一点。
答案 2 :(得分:1)
来电test(7);
中的'7'为int
,不会自动转换为short
。
当您声明并初始化short
值时,它会起作用,但这是编译器的特例。方法调用不存在这种特殊情况。