当前位置: 首页 > 面试题库 >

为什么我可以为短类型变量分配整数文字,而不给短类型方法参数分配整数?

伏默
2023-03-14
问题内容

我为什么可以这样做:

short a = 5;

但这不是:

void setNum(short a);

setNum(5);

它抛出:

从int到short可能的有损转换

我知道5是整数文字,您必须强制转换。我还了解,如果该值不是常数,则很明显需要抛出该错误,因为该值可能达到了short类型的限制。但是,为什么如果编译器知道我正在传递一个short可以容纳的常量(如在赋值中),则它不允许它进行编译?我的意思是,它们之间有什么区别?


问题答案:

为了理解为什么赋值类型转换在调用被拒绝的同时起作用的原因,必须参考Java语言规范主题以缩小原始转换和转换的上下文:赋值上下文和调用上下文。

根据JLS,在以下 情况下, 允许在 赋值上下文中 进行变窄原语转换:

如果变量的类型为byte,short或char,并且常量表达式的值可表示为变量的类型,则可以使用缩窄的原始转换。

… 分配给时,您的情况与int常量匹配。5``short a

调用上下文中 不允许进行这种变窄的原始转换,这解释了为什么setNum(short)在传递int常量时调用失败的原因5

但是,为什么如果编译器知道我正在传递一个short可以容纳的常量(如在赋值中),则它不允许它进行编译?我的意思是,它们之间有什么区别?

JLS一定不想让编译器负担这种额外的逻辑。在调用的情况下,与形式参数类型匹配的参数是一个表达式-
编译器已经必须确定类型,但是它不必检查表达式的值是否也可以安全地缩小。在这种情况下,是一个常数,它很清楚, 我们
认为它可以,但在执行上下文的编译器允许不与理会检查,并在-其实正确禁止它。

应当非常清楚的是,当允许使用表达式时,在不损失精度的情况下无法进行缩小的bug越容易出现漏洞,因此JLS和编译器在所有情况下都不允许这样做。

在数字上下文中也是如此,因此声明

short a = 5;short b = a * 5;

尽管显然由正确缩小的常数组成,但…同样也是不允许的。



 类似资料: