【问题标题】:Cannot convert from to - Java's implicit type conversion and an unary operator无法从 to 转换 - Java 的隐式类型转换和一元运算符
【发布时间】:2021-06-16 18:57:58
【问题描述】:
byte b1 = 3 + 5;

文字353 + 5 的类型为int。 上面的表达式有效是因为 Java 在内部将 3 + 5 的结果从 int 转换为 byte,或者?

对于b2,同样的解释应该是有效的:

    byte b1 = 3 + 5;
    byte b2 = b1 + 5; // Type mismatch: cannot convert from int to byte

但事实并非如此。

为什么?

【问题讨论】:

  • 区别:35是编译时常量,所以3 + 5可以在编译时求值,整行简化为byte b1 = 8;。但是b1 不是编译时间常数,所以这不适用于byte b2 = b1 + 5; 行。
  • 观看此对话,也许它可以帮助stackoverflow.com/questions/9581530/…
  • 如果您声明 b1 final,则第二次对话有效。编译器只是考虑非最终变量可能已被第二行更改的可能性,因此太大以适合另一个字节
  • + 的操作数经过二进制数值提升:在第二种情况下,它实际上是(int) b1 + 5,其结果是一个非编译时常量int。在第一种情况下,两个操作数都是编译时常量(和整数),因此结果是编译时常量 int;编译器可以检查结果是否在byte 的范围内,因此可以隐式缩小结果。

标签: java


【解决方案1】:

+ 的操作数经过二进制数字提升:也就是说,它们在必要时被加宽以使其兼容加法。规则很简单:

  • 如果任一操作数是双精度数,则将另一个操作数加宽为双精度数
  • 如果任一操作数是浮点数,则将另一个加宽为浮点数
  • 如果任一操作数是 long,则将另一个操作数加宽为 long
  • 否则,将它们都扩大到 int

在第二种情况下,它实际上是(int) b1 + 5,其结果是一个非编译时常量int。这不能保证在byte的范围内,所以编译器报错。

在第一种情况下,两个操作数都是编译时常量 int,所以结果是编译时常量 int;编译器可以检查结果是否在byte 的范围内,因此可以隐式缩小结果范围。

【讨论】:

    【解决方案2】:

    ints 在您之前的分配中被隐式转换为bytes,为了模仿最后一条语句中的效果,您需要在 java 将 b1 + 5 提升为 int 后显式执行此操作,如下所示:

    byte b2 = (byte) b1 + 5;
    

    或者,如果您将b1 声明为final,编译器将检查范围并按照您最初的预期进行赋值(使用隐式转换),因为3 + 5它在bytes 的范围内并且 b1 不会改变它的值 (3):

    final byte b1 = 3;
    byte b2 = b1 + 5;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-01
      • 1970-01-01
      • 2018-08-20
      • 1970-01-01
      • 2012-10-04
      相关资源
      最近更新 更多