我认为任何算术表达式的结果至少是一个int.7/3是一个表达式 - 它有一个运算符(除法).
但为什么编译好呢?
byte b1 = 7 / 3; // 7/3 is not a literal?
short b2 = 7 / 3; // 7/3 is not a literal?
char b3 = 7 / 3; // 7/3 is not a literal?
Run Code Online (Sandbox Code Playgroud)
和f1()编译好吗?
byte f1() {
return 7 / 3; // Why is it allowed? Why isn't 7 / 3 an int ?
}
byte f2(int x) {
return x / 3; // c.ERR - type mismatch
}
byte f3(byte x) {
return x / 3; // c.ERR - type mismatch
}
Run Code Online (Sandbox Code Playgroud)
PS问题是不同的,因为我知道7/3会因整数除法而给出2(舍入为零),但它应该是一个int,而不是字节或短.
Jac*_* G. 11
byte f1() {
return 7 / 3; // Why is it allowed? Why isn't 7 / 3 an int ?
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码片段中,结果在字节范围(-128to 127)内,并且编译器足够聪明,可以意识到它可以隐式地将int结果转换byte为由方法返回的结果.
JLS 14.17:当一个
return带有Expression的语句出现在方法声明中时,Expression必须可赋值(第5.2节)到声明的方法返回类型,否则会发生编译时错误.JLS 5.2:如果表达式是一个常量表达式(§15.28类型的)
byte,short,char,或int:
- 如果变量是type
byte,short或char,则可以使用缩小的基元转换,并且常量表达式的值可以在变量的类型中表示.
byte f2(int x) {
return x / 3; // c.ERR - type mismatch
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码片段中,因为它x是一个int,它可以是一个大数,当除以时3,将不在范围byte内,因此编译器知道它不应该尝试隐式地将它转换为a byte,因为结果可能不是期望.
JLS 14.17:当一个
return带有Expression的语句出现在方法声明中时,Expression必须可赋值(第5.2节)到声明的方法返回类型,否则会发生编译时错误.
byte f3(byte x) {
return x / 3; // c.ERR - type mismatch
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码片段中,当使用a byte和a进行算术运算时int,byte会自动将其上传到int(如JLS中所定义).这导致与第二个相同的情况; 即使我们知道结果必须在byte范围内,编译器也不会,因为除以3可以改为乘以9999....
JLS 15.17:对操作数执行二进制数字提升(第5.6.2节).
JLS 5.6.2:应用扩展原语转换(第5.1.2节)来转换由以下规则指定的一个或两个操作数:
如果任一操作数是类型
double,则另一个操作数转换为double.否则,如果任一操作数是类型
float,则另一个操作数转换为float.否则,如果任一操作数是类型
long,则另一个操作数转换为long.否则,两个操作数都将转换为类型
int.
| 归档时间: |
|
| 查看次数: |
177 次 |
| 最近记录: |