检查以下代码段:
int a=20;
int b=30;
byte c= (a>b)? 20:30;
Error:
incompatible types: possible lossy conversion from int to byte
byte c= (a>b)? 20:30;
int a=20;
int b=30;
byte h1=70;
byte c= (a>b)? 20:h1;
int a=20;
int b=30;
byte h1=70;
byte h2=89;
byte c= (a>b)? h1:h2;
byte c= (true)? 20:30;
除了代码片段1以外,所有这些都可以编译。如何证明这种行为合理?如果代码片段1产生“可能的有损转换”错误,则代码片段2和4也应该给出,因为它们仍包含类型int
的文字。他们为什么编译成功?
答案 0 :(得分:28)
J.L.S 15.25.解释了此行为。
代码段1:
如果第二个操作数和第三个操作数具有相同的类型(可能为空类型),则这是条件表达式的类型
第二个操作数和第三个操作数均为int
文字,因此表达式的类型也为int
,如果没有显式强制转换,则不能将其分配给byte
变量。因此出现编译错误。
代码段2:
如果其中一个操作数的类型为T,其中T为字节,short或char,而另一个操作数的类型为int的常量表达式(第15.28节),其值可以在类型T中表示,则该类型为条件表达式是T。
一个操作数是byte
,另一个是int
文字,其值可以表示为byte
,因此表达式的类型为byte
,可以被分配给byte
变量。
代码段3:
如果第二个操作数和第三个操作数具有相同的类型(可能为空类型),则这是条件表达式的类型
第二个操作数和第三个操作数均为byte
,因此表达式的类型为byte
,可以将其分配给byte
变量。
代码段4:
由于所有3个操作数都是常量,因此整个三元表达式都是常量表达式,因此编译器将此表达式视为简单的赋值-byte c = 20;
-有效。
答案 1 :(得分:8)
此行为在language spec中进行了描述。
案例1和3的描述相同:
如果第二个操作数和第三个操作数具有相同的类型,那么这就是条件表达式的类型。
在情况1中,操作数的类型为int,因此整个表达式的类型为int,因此不兼容。在情况3中,类型为byte的操作数,因此结果是兼容的。
第2种情况对我来说是令人惊讶的:我本来也希望失败,因为int操作数会导致条件表达式为int类型。
但是,此行为在以下几点中进行了描述:
如果其中一个操作数是T类型,其中Tisbyte,short或char,而另一个操作数是int类型的常量表达式(§15.28),其值可以在T类型中表示,则条件类型表达式是T。
20是一个适合字节的常量表达式,因此结果是一个字节。
第4种情况也通过第1种情况和第3种情况使用的“相同类型的操作数”进行了描述;但是,条件现在不变的事实使其成为constant expressions。
如Assignment contexts中所述,将int类型的常量表达式分配给较窄类型的变量时会隐式缩小其范围:
如果变量的类型为byte,short或char,并且常量表达式的值可以表示为变量的类型,则可以使用缩窄的原始转换。