我为什么可以这样做:
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;
尽管显然由正确缩小的常数组成,但…同样也是不允许的。
问题内容: 考虑以下代码: 编译产生错误 因为表达式i / j的类型显然是int,因此必须将其强制转换为short。 为什么类型不短? 问题答案: 从Java规范: 5.6.2二进制数值提升 当运算符将二进制数值提升应用于一对操作数时,每个操作数必须表示一个数值类型的值,以下规则按顺序适用,并根据需要使用加宽转换(第5.1.2节)来转换操作数: 如果一个操作数的类型为double,则另一个将转换为
从int到short的转换可能有损 我知道5是一个整数字面,你必须对它进行强制转换。我还理解,如果该值不是常量,那么显然需要抛出该错误,因为可能该值达到了短类型的极限。但是,如果编译器知道我传递的是一个short可以保持的常量(如赋值中的那样),为什么它不让它编译呢?我是说,它们之间有什么区别?
问题内容: 为什么以下代码无法编译 但是以下确实可以编译 在这两种情况下,我不只是将整数值分配给char吗? 问题答案: 可以将A 分配给不带强制转换的,因为这是扩大的转换。反之,将a 转换为a 需要转换,因为这是缩小的转换。 另请参见JLS。第5章。转换和升级。
我刚刚更新到Dart2和Flatter sdk:' 无法将参数类型“Object”指定给参数类型“ImageProvider”。), 我只是从弗利特开始,不知道该去哪里找别的。
由于最近的更新,我正面临这个问题,请伙计们帮帮我