【问题标题】:Type mismatch: cannot convert from int to byte using ternary operator类型不匹配:无法使用三元运算符从 int 转换为 byte
【发布时间】:2017-03-19 18:44:21
【问题描述】:

在一个使用字节数组操作的项目上工作,我试图写这样的东西:

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 语句中使用字节赋值?

【问题讨论】:

  • 另外有趣:为什么byte enabledByte = true ? 0x01 : 0x00; 编译?
  • @ldz 这是因为true ? 0x01 : 0x00 是一个常量表达式,这与使用变量而不是true 文字的情况不同。请参阅我的回答,了解语言规范如何规定这一点。

标签: java byte


【解决方案1】:

0x000x01int 文字:它们是具有 int 类型的表达式。 int 通常不能分配给 byte,但如果表达式是编译时常量,则它可以,前提是值在 byte 的范围内。

使用条件,赋值为编译时常量:

if (enabled) {
  enabledByte = 0x01;
} else {
  enabledByte = 0x00;
}

从编译器的角度来看,这些赋值是完全独立的。有一个语句将常量值 1 分配,还有一个语句将常量值 0 分配。

对于每条语句,编译器可以保证它适合字节的范围,所以它会自动将分配的值缩小到字节。

但是,使用条件运算符的赋值:

enabledByte = enabled ? 0x01 : 0x00;

rhs 表达式的类型为int,但不是编译时常量,因为enabled 在编译时是未知的。两个可能的值 编译时常量并不重要,并且两者都适合 byte:非常量的第一个操作数使其非常量。因此,条件运算符表达式的结果不能自动缩小。

对此最有效的解决方案是将第二个和第三个操作数强制转换为byte

enabled ? (byte) 0x01 : (byte) 0x00

这比

(byte) (enabled ? 0x01 : 0x00)

因为后者将在运行时强制转换,每次计算表达式时,而前者不会:操作数在编译时已经是字节,因此不需要强制转换。

【讨论】:

    【解决方案2】:

    数字字面量自然是 int 类型,而不是 byte

    该语言具有从数字文字 (byte 的特殊隐式转换,因此您的第二个示例不需要强制转换。

    但是,将文字包装在条件运算符中会创建一个不是文字的 int 类型的表达式,因此您需要强制转换。

    【讨论】:

      【解决方案3】:

      您至少需要一次强制转换才能将三元表达式翻转为 byte,由于三元,它默认为 int

      byte enabledByte = enabled ? (byte) 0x01 : 0x00; 
      

      如果你使用十进制文字,它的工作方式是一样的

      byte enabledByte = enabled ? (byte) 1 : 0; 
      

      另见JLS-15.25.2 - Numeric Conditional Expressions(部分)

      否则,二进制数值提升(§5.6.2)应用于操作数类型,条件表达式的类型是第二个和第三个操作数的提升类型。

      【讨论】:

        【解决方案4】:

        控制从intbyte 的缩小转换的规则在语言规范的assignment contexts 部分中指定(强调常量表达式):

        此外,如果表达式是 byteshortcharint 类型的常量表达式(第 15.28 节):

        • 如果变量的类型是byteshortchar,并且常量表达式的值可以用变量的类型表示,则可以使用缩小原语转换。

        ...

        如果无法通过赋值上下文中允许的转换将表达式的类型转换为变量的类型,则会发生编译时错误。

        与整数文字不同,三元条件表达式enabled ? 0x01 : 0x00 不是constant expression。因此,不能使用窄化转换进行隐式转换。

        请注意,您可以通过强制转换条件表达式的操作数之一来解决错误:

        byte enabledByte = enabled ? (byte) 0x01 : 0x00;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-12-27
          • 1970-01-01
          • 2020-06-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多