Java 类型不匹配:无法使用三元运算符从int转换为byte
在一个利用字节数组操作的项目中,我尝试编写如下内容:Java 类型不匹配:无法使用三元运算符从int转换为byte,java,byte,Java,Byte,在一个利用字节数组操作的项目中,我尝试编写如下内容: boolean enabled = getEnabled(); byte enabledByte = enabled ? 0x01 : 0x00; // compile error 我面临的问题是,上述内容将无法编译 类型不匹配:无法从int转换为byte 但是,如果我将其扩展到以下内容,它将毫无问题地工作: boolean enabled = getEnabled(); byte enabledByte; if (enabled) {
boolean enabled = getEnabled();
byte enabledByte = enabled ? 0x01 : 0x00; // compile error
我面临的问题是,上述内容将无法编译
类型不匹配:无法从int转换为byte
但是,如果我将其扩展到以下内容,它将毫无问题地工作:
boolean enabled = getEnabled();
byte enabledByte;
if (enabled) {
enabledByte = 0x01;
} else {
enabledByte = 0x00;
}
把我引向这个问题
为什么我不能在简短的if语句中使用字节赋值
数字文字的类型自然是
int
,而不是byte
该语言有一个特殊的隐式转换,从数值文本(<128)到字节
,因此您的第二个示例不需要强制转换
但是,将文本包装在条件运算符中会创建一个类型为
int
的表达式,它不是一个文本,因此您需要强制转换。您至少需要一个强制转换才能将三元表达式翻转为字节
,由于三元表达式,它默认为int
byte enabledByte = enabled ? (byte) 0x01 : 0x00;
如果使用十进制文字,其工作方式相同
byte enabledByte = enabled ? (byte) 1 : 0;
另请参见以下内容(部分)
否则,二进制数字提升()将应用于操作数类型,条件表达式的类型是第二个和第三个操作数的提升类型
语言规范(强调常量表达式)一节中规定了从
int
到byte
的窄化转换规则:
此外,如果表达式是类型为byte
、short
、char
或int
的常量表达式(§15.28):
- 如果变量的类型是
、字节
或短
,并且常量表达式的值可以用变量的类型表示,则可以使用缩小原语转换字符
是否启用?0x01:0x00
与整数文本不同,不是a。因此,不能使用窄化转换隐式转换它
请注意,可以通过强制转换条件表达式的一个操作数来解决此错误:
byte enabledByte = enabled ? (byte) 0x01 : 0x00;
0x00
和0x01
是int
文本:它们是类型为int
的表达式。通常不能将int
赋值给字节
,但如果表达式是编译时常量,只要值在字节
范围内,则可以赋值
对于条件,赋值为编译时常量:
if (enabled) {
enabledByte = 0x01;
} else {
enabledByte = 0x00;
}
这些赋值与编译器的观点完全不同。有一条语句指定常量值1,还有一条语句指定常量值0
对于每一条语句,编译器都可以保证符合字节范围,因此它会自动将赋值缩小到字节
但是,使用条件运算符的赋值:
enabledByte = enabled ? 0x01 : 0x00;
rhs表达式的类型为int
,但不是编译时常量,因为编译时不知道enabled
。这两个可能的值是否是编译时常量并不重要,并且都可以放入字节中:非常量的第一个操作数使其成为非常量。因此,条件运算符表达式的结果不能自动缩小
最有效的解决方案是将第二个和第三个操作数强制转换为字节
:
enabled ? (byte) 0x01 : (byte) 0x00
这比
(byte) (enabled ? 0x01 : 0x00)
因为后者将在运行时强制转换,每次计算表达式时,前者不会:操作数在编译时已经是字节,因此不需要强制转换。另外有趣的是:为什么byte enabledByte=true?0x01:0x00代码>编译?@ldz这是因为真的吗?0x01:0x00
是一个常量表达式,与使用变量而不是true
文本不同。请参阅我的答案,了解语言规范如何规定这一点。