如果从数组中复制了Java,为什么Java需要对最终变量进行显式强制转换? [英] Why does Java require an explicit cast on a final variable if it was copied from an array?

查看:177
本文介绍了如果从数组中复制了Java,为什么Java需要对最终变量进行显式强制转换?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从以下代码开始......

Starting with the following code...

byte foo = 1;
byte fooFoo = foo + foo;

当我尝试编译此代码时,我会收到以下错误...

When I try compiling this code I will get the following error...


错误:(5,27)java:不兼容类型:从int到byte的可能有损转换

Error:(5, 27) java: incompatible types: possible lossy conversion from int to byte

...但是如果 foo 是最终的......

... but if foo is final...

final byte foo = 1;
final byte fooFoo = foo + foo;

文件将成功编译。

继续下面的代码...

Moving on to the following code...

final byte[] fooArray = new byte[1];
fooArray[0] = 1;

final byte foo = fooArray[0];
fooArray[0] = 127;

System.out.println("foo is: " + foo);

...将打印

foo is: 1

...这很好。该值将复制到最终变量,不能再更改。使用数组中的值不会更改 foo 的值(如预期的那样......)。

... which is fine. The value is copied to a final variable and it can not be changed any more. Playing with the value in the array does not change the value of the foo (as expected...).

为什么以下需要演员?

final byte[] fooArray = new byte[1];
fooArray[0] = 1;
final byte foo = fooArray[0];
final byte fooFoo = foo + foo;

这与这个问题中的第二个例子有什么不同?为什么编译器会给我以下错误?

How is this different than the second example in this question? Why is the compiler giving me the following error?


错误:(5,27)java:不兼容类型:可能有损转换从int到byte

Error:(5, 27) java: incompatible types: possible lossy conversion from int to byte

这怎么可能发生?

推荐答案

JLS(§5.2 )具有常量表达式的赋值转换的特殊规则:

The JLS (§5.2) has special rules for assignment conversion with constant expressions:


此外,如果表达式是一个常量表达式(§15.28)类型 byte short char ,或 int


  • 如果类型为变量是 byte short ,或 char ,以及常量表达式的值表示为e在变量的类型中。

  • A narrowing primitive conversion may be used if the type of the variable is byte, short, or char, and the value of the constant expression is representable in the type of the variable.

如果我们按照上面的链接,我们会看到这些常量表达式的定义

If we follow the link above, we see these in the definition of constant expression:



  • 原始类型的文字和类型的文字字符串

  • 添加剂运算符 + -

  • 简单名称(§6.5.6.1)引用常量变量(§4.12.4)。

  • Literals of primitive type and literals of type String
  • The additive operators + and -
  • Simple names (§6.5.6.1) that refer to constant variables (§4.12.4).

如果我们按照上面的第二个链接,我们看到

If we follow the second link above, we see that


一个原始变量输入 String ,即 final 并使用编译时常量表达式初始化(​​§15.28),被称为常量变量

A variable of primitive type or type String, that is final and initialized with a compile-time constant expression (§15.28), is called a constant variable.

因此 foo + foo 只能分配给 fooFoo 如果 foo 常量变量。要将其应用于您的案例:

It follows that foo + foo can only be assigned to fooFoo if foo is a constant variable. To apply that to your cases:


  • byte foo = 1; 定义常量变量,因为它不是 final

  • byte foo = 1; does not define a constant variable because it's not final.

final byte foo = 1; 确定定义常量变量,因为它是 final 并使用常量表达式(原始文字)初始化。

final byte foo = 1; does define a constant variable, because it's final and initialized with a constant expression (a primitive literal).

最后一个字节foo = fooArray [0]; 定义一个常量变量,因为它没有用常量初始化表达

final byte foo = fooArray[0]; does not define a constant variable because it's not initialized with a constant expression.

注意 fooFoo 本身最终无关紧要。

这篇关于如果从数组中复制了Java,为什么Java需要对最终变量进行显式强制转换?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆