如果从数组中复制了Java,为什么Java需要对最终变量进行显式强制转换? [英] Why does Java require an explicit cast on a final variable if it was copied from an array?
问题描述
从以下代码开始......
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
, orchar
, 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:
- 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 isfinal
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 notfinal
.
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屋!