不一致 "possible lossy conversion from int to byte" 编译时错误

Inconsistent "possible lossy conversion from int to byte" compile-time error

检查以下代码片段:

片段#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;

除代码段 #1 外,所有这些都可以正常编译。这种行为如何合理化?如果代码段 #1 产生 "possible lossy conversion" 错误,代码段 #2 和 4 也应该如此,因为它们仍然包含类型 int 的文字。为什么他们编译成功?

J.L.S 15.25. 解释了这种行为。

片段#1:

If the second and third operands have the same type (which may be the null type), then that is the type of the conditional expression

第二个和第三个操作数都是int字面量,所以表达式的类型也是int,如果没有显式转换就不能赋值给byte变量。因此编译错误。

代码段#2:

If one of the operands is of type T where T is byte, short, or char, and the other operand is a constant expression (§15.28) of type int whose value is representable in type T, then the type of the conditional expression is T.

一个操作数是byte,另一个是int字面量,其值可以表示为byte,所以表达式的类型是byte,可以分配给 byte 变量。

片段#3:

If the second and third operands have the same type (which may be the null type), then that is the type of the conditional expression

第二个和第三个操作数都是byte,所以表达式的类型是byte,可以赋值给一个byte变量

片段#4:

由于所有 3 个操作数都是常量,整个三元表达式是一个常量表达式,因此编译器将此表达式视为一个简单的赋值 - byte c = 20; - 这是有效的。

language spec 中描述了此行为。


案例1和案例3描述的是同一个点:

If the second and third operands have the same type, then that is the type of the conditional expression.

情况1,操作数是int类型,所以整个表达式都是int类型,所以不兼容。在情况 3 中,字节类型的操作数,因此结果是兼容的。


情况 2 让我感到惊讶:我原以为它也会失败,因为 int 操作数会导致条件表达式为 int 类型。

但是,此行为在以下几点中进行了描述:

If one of the operands is of type T where Tis byte, short, or char, and the other operand is a constant expression (§15.28) of type int whose value is representable in type T, then the type of the conditional expression is T.

20是一个适合字节的常量表达式,因此结果是一个字节。


情况 4 也由用于情况 1 和 3 的 "operands of the same type rule" 描述;然而,条件现在不变的事实使其成为 constant expressions.

int 类型的常量表达式在分配给较窄类型的变量时隐式变窄,如 Assignment contexts:

中所述

A narrowing primitive conversion may be used if the variable is of type byte, short, or char, and the value of the constant expression is representable in the type of the variable.