【问题标题】:Why there is no error when a final int is assigned to a byte [duplicate]为什么将最终int分配给字节时没有错误[重复]
【发布时间】:2019-01-08 15:59:44
【问题描述】:

为什么会报错

       int i=123;
       byte b=i;

但在这种情况下不是

      final int i=123;
      byte b=i;

【问题讨论】:

  • @Turamarth 很好发现!那里的答案也解释了这一点。
  • 但是变量都是字节类型而不是int
  • @alia 是的,但解释是一样的。
  • @alia 没关系。关键部分是您可以将非最终 int 更改为对于字节而言太大的东西。只有使 int final 会向编译器显示 int 将适合字节。另一个问题只是将一个大 int 替换为两个较小的字节相加。
  • @alia 如前所述,它与int 是否适合byte 有关。看到这个设置final int i 大于127byte 的最大值)或小于-128byte 的最小值),您将再次遇到编译错误。

标签: java


【解决方案1】:

当您使用常量表达式初始化final 变量时,它将变为compile-time constant。本质上,当代码被编译时,它只会对添加变量的任何地方的值进行硬编码。您可以在字节码中看到这一点:

 0  bipush 123
 2  istore_1 [i]
 3  bipush 123
 5  istore_2 [b]

如您所见,它将值123 直接推入byte(与byte b = 123 相同),这是byte 的有效值。它不适用于超出字节允许范围的值。

如果变量不是final(或未使用常量表达式初始化),那么编译器会将其视为普通变量,并应用普通的赋值规则。这意味着要将 int 分配给需要强制转换的字节:

int i = 123;
byte b = (byte) i;

产生这个字节码:

0  bipush 123
2  istore_1 [i]
3  iload_1 [i]
4  i2b
5  istore_2 [b]

【讨论】:

  • 但是当变量不是final时会发生什么?
  • @alia 在这种情况下,编译器无法在编译时替换该值,并且将应用正常的分配规则(也需要转换为 byte)。在final 的情况下,它基本上不需要关心i 的类型,因为在分配b 时不使用它。
【解决方案2】:

boolean、byte、short、int、long默认都是int,都是int,只要不超出其取值范围就可以赋值

final修饰的变量是在编译时确定的,不能更改。

final修饰的变量不会自动改变类型

final int i = 127;
byte b = i;

final int i = 128;
byte b = i;        // There will be compilation errors

【讨论】:

  • 但是当变量不是最终变量时实际会发生什么?为什么我们会得到错误
  • @alia final 修改的变量不会改变,会被JVM优化。当final修饰的变量赋值后,会根据left变量的类型进行变换,作为final变量的final类型。
猜你喜欢
  • 2019-10-26
  • 1970-01-01
  • 1970-01-01
  • 2014-10-10
  • 1970-01-01
  • 2015-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多