为什么“短三十= 3 * 10”是合法的任务?


102

如果short自动升级为int算术运算,那么为什么是:

short thirty = 10 * 3;

short变量的合法赋值thirty

反过来,这是:

short ten = 10;
short three = 3;
short thirty = ten * three; // DOES NOT COMPILE AS EXPECTED

以及这个:

int ten = 10;
int three = 3;
short thirty = ten * three; // DOES NOT COMPILE AS EXPECTED

不会编译,因为不允许在未按预期进行转换的情况下int为a 赋值short

关于数字文字,有什么特别的事情吗?


23
short thirty = 10 * 3;最有可能被short thirty = 30;编译器所代替,这是一个有效的语句。(不过,我必须查找相关的JLS部分)。
托马斯

编译器10 * 3使用结果计算并初始化变量。在您的非工作示例中,计算是在运行时进行的,JVM进行了强制转换。
Felix

我认为这是stackoverflow.com/questions/30346587/java-char-to-byte-castingstackoverflow.com/questions/9379983/…的副本。但是:请注意final int ten = 10; final int three = 3; short thirty = ten * three;编译正常。
Marco13

7
If short is automatically promoted to int in arithmetic operations-没关系。无论是10也不3是空头,也不是提拔,他们是文字。
马修(Matthew)

@MatthewRead:但是即使是文字,它们也必须作为特定的数据类型进行评估,对吗?是,编译器将s 10和s 3评估为ints 是真的吗?
拉尔斯

Answers:


139

因为编译器本身10*3编译时会替换为30 。因此,有效地:short thirty = 10 * 3是在编译时计算的。

试着改变tenthreefinal short(使他们的编译时间常数),并看看会发生什么:P

检查javap -v 两个验证码(10*3final short)的字节码。您将看到几乎没有区别。

好的,这是不同情况下的字节码差异。

情况1 :

Java代码:main(){short s = 10 * 3; }

字节码:

stack=1, locals=2, args_size=1
         0: bipush        30  // directly push 30 into "s"
         2: istore_1      
         3: return   

情况-2:

public static void main(String arf[])  {
   final short s1= 10;
   final short s2 = 3;
   short s = s1*s2;
}

字节码:

  stack=1, locals=4, args_size=1
         0: bipush        10
         2: istore_1      
         3: iconst_3      
         4: istore_2      
         5: bipush        30 // AGAIN, push 30 directly into "s"
         7: istore_3      
         8: return   

情况-3:

public static void main(String arf[]) throws Exception {
     short s1= 10;
     short s2 = 3;
     int s = s1*s2;
}

字节码:

stack=2, locals=4, args_size=1
         0: bipush        10  // push constant 10
         2: istore_1      
         3: iconst_3        // use constant 3 
         4: istore_2      
         5: iload_1       
         6: iload_2       
         7: imul          
         8: istore_3      
         9: return 

在上述情况下,103来自局部变量s1s2


17
喜欢Try changing ten and three to final short运动:)
Sergey Pauk 2015年

1
@SergeyPauk-这对理解编译时间常数非常重要..适用于所有原语(也适用于字符串。):)
TheLostMind 2015年

1
@TheLostMind我建议一个更好的措辞you will see that there's no difference (between those two lines in the decompiled code)原因,这不是您的意思吗?
谢尔盖·帕克

4
有趣的是,这也意味着case 10*3:和类似的东西在转换结构中是合法的。
壁虎天花板

5
和类似的枚举构造。实际上,对位域枚举常量使用诸如1 << 5之类的东西是习惯用法。
Bathsheba,2015年

18

是的,字面量情况有一些特殊的情况:10 * 3将在编译时进行评估。因此,您不需要(short)对乘法文字进行显式转换。

ten * three 无法在编译时评估,因此需要进行显式转换。

如果tenthree被标记将是一回事final


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.