使用字节数组操作处理项目时,我试图写这样的东西:
boolean enabled = getEnabled();
byte enabledByte = enabled ? 0x01 : 0x00; // compile error
我面临的问题是上述内容无法编译。
类型不匹配:无法从int转换为字节
但是,如果我将其扩展为以下内容,则可以正常运行:
boolean enabled = getEnabled();
byte enabledByte;
if (enabled) {
enabledByte = 0x01;
} else {
enabledByte = 0x00;
}
引导我回答问题
为什么我不能在短if语句中使用字节赋值?
答案 0 :(得分:2)
数字文字自然属于int
类型,而不是byte
。
该语言具有从数字文字(< 128)到{{1}}的特殊隐式转换,因此您的第二个示例不需要演员。
但是,将文字包装在条件运算符中会创建一个类型为byte
的表达式,该表达式不是文字,因此您需要强制转换。
答案 1 :(得分:2)
0x00
和0x01
是 int
文字:它们是int
类型的表达式。 int
通常不能分配给byte
,但如果表达式是编译时常量,则可以 ,前提是该值在{{1}范围内}}
对于条件,赋值是编译时常量:
byte
这些分配与编译器的观点完全不同。有一个语句指定常量值1,一个语句指定常量值0。
对于每个语句,编译器可以保证适合字节范围,因此它会自动将指定的值缩小为byte。
但是,使用条件运算符赋值:
if (enabled) {
enabledByte = 0x01;
} else {
enabledByte = 0x00;
}
rhs表达式的类型为enabledByte = enabled ? 0x01 : 0x00;
,但不是编译时常量,因为在编译时不知道int
。两个可能的值是编译时常量并不重要,两者都适合enabled
:非常数第一个操作数使其非常数。因此,条件运算符表达式的结果不能自动缩小。
最有效的解决方案是将第二个和第三个操作数强制转换为byte
:
byte
这比
更好enabled ? (byte) 0x01 : (byte) 0x00
因为后者将在运行时进行转换,所以每次计算表达式时,前者都不会:操作数在编译时已经是字节,因此不需要强制转换。
答案 2 :(得分:0)
你需要至少一个演员才能将三元表达式翻转为byte
,因为三元组,它默认为int
。
byte enabledByte = enabled ? (byte) 0x01 : 0x00;
如果使用十进制文字
,它的工作方式相同byte enabledByte = enabled ? (byte) 1 : 0;
另见JLS-15.25.2 - Numeric Conditional Expressions(部分)
否则,二进制数字提升(§5.6.2)将应用于操作数类型,条件表达式的类型是第二个和第三个操作数的提升类型。
答案 3 :(得分:0)
管理从int
到byte
的缩小转换的规则在assignment contexts的语言规范部分中指定(强调常量表达式):
此外,如果表达式是
byte
,short
,char
或int
类型的常量表达式(第15.28节) :
- 如果变量的类型是
byte
,short
或char
,则可以使用缩小的基元转换,并且常量表达式的值可以在类型中表示。变量...
如果表达式的类型无法通过赋值上下文中允许的转换转换为变量的类型,则会发生编译时错误。
三元条件表达式enabled ? 0x01 : 0x00
不是constant expression,与整数文字不同。因此,不能使用缩小转换隐式转换它。
请注意,您可以通过转换条件表达式的一个操作数来解决错误:
byte enabledByte = enabled ? (byte) 0x01 : 0x00;