不一致的“从 int 到 byte 的可能有损转换”编译时错误

检查以下代码片段:


片段 #1

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;

片段 #2

int a=20;

int b=30;

byte h1=70;

byte c= (a>b)? 20:h1;

片段 #3

int a=20;

int b=30;

byte h1=70;

byte h2=89;

byte c= (a>b)? h1:h2;

片段 #4

byte c= (true)? 20:30;

除了 Snippet #1 之外,所有这些都可以正常编译。这种行为如何合理化?如果代码段 #1 产生“可能的有损转换”错误,则代码段 #2 和 4 也应该如此,因为它们仍然包含 type 的文字int。他们为什么编译成功?


慕婉清6462132
浏览 168回答 2
2回答

慕尼黑的夜晚无繁华

JLS 15.25。解释了这种行为。片段#1:如果第二个和第三个操作数具有相同的类型(可能是空类型),那么这就是条件表达式的类型第二个和第三个操作数都是int字面量,所以表达式的类型也是int,不能在byte没有显式转换的情况下分配给变量。因此编译错误。片段#2:如果其中一个操作数是 T 类型,其中 T 是 byte、short 或 char,而另一个操作数是 int 类型的常量表达式(第 15.28 节),其值可以用 T 类型表示,则条件表达式的类型是T.一个操作数是 a byte,另一个是int字面量,其值可以表示为byte,所以表达式的类型是byte,可以赋值给一个byte变量。片段#3:如果第二个和第三个操作数具有相同的类型(可能是空类型),那么这就是条件表达式的类型第二个和第三个操作数都是byte,所以表达式的类型是byte,可以赋值给一个byte变量。片段#4:由于所有 3 个操作数都是常量,所以整个三元表达式是一个常量表达式,因此编译器将此表达式视为一个简单的赋值 - byte c = 20;- 这是有效的。

MM们

语言规范中描述了此行为。案例1和案例3用相同的点来描述:如果第二个和第三个操作数具有相同的类型,那么这就是条件表达式的类型。在情况1中,操作数是int类型,所以整个表达式是int类型,所以不兼容。在情况 3 中,字节类型的操作数,因此结果是兼容的。情况 2 让我感到惊讶:我预计它也会失败,因为 int 操作数会导致条件表达式为 int 类型。但是,此行为在以下几点中进行了描述:如果其中一个操作数是 T 类型,其中 T 是 byte、short 或 char,而另一个操作数是 int 类型的常量表达式(§15.28),其值可以用 T 类型表示,则条件表达式的类型是 T .20 是一个适合字节的常量表达式,因此结果是一个字节。情况 4 也由用于情况 1 和 3 的“相同类型规则的操作数”来描述;然而,条件现在是常量的事实使它成为常量表达式。分配给较窄类型的变量时,int 类型的常量表达式会隐式变窄,如赋值上下文中所述:如果变量是 byte、short 或 char 类型,并且常量表达式的值可以用变量的类型表示,则可以使用收缩原始转换。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java