文字的算术运算是在编译时还是运行时计算的?

我有以下内容:

double timeInMinutes = (double) timeInMilliseconds / (1000 * 60); 

操作(1000 * 60)是在编译时还是在运行时完成的? 换句话说,在上面的代码片段和运行时间之间是否存在性能差异:

 double timeInMinutes = (double) timeInMilliseconds / 60000; 

编辑:我的问题不同于Java编译器是否会预先计算文字的总和? 因为我在算术运算中混合使用变量和文字。 这是一个很小的区别,但正如@TagirValeev在评论中指出的那样( 在编译时或运行时计算文字的算术运算? ),有些文字虽然可以预先编译,但是没有预编译。

根据JLS§15.2 – 表达forms

某些表达式具有可在编译时确定的值。 这些是常量表达式(§15.28)。

*, /, and %这样的乘法运算符属于常量表达式,因此它将在编译时确定。

@SergeyMorozov写得比我快,并且得到字节码certificate( #2 = Integer 60000 ),但这里是实际证据,上面是理论/官方声明:

尝试使用1000 * 6060000生成字节代码,您将看到相同的字节代码指令,因此运行时性能相同。

Java类:

 public class Test { public static void main(String[] args) { int compileTest = 1000 * 60; } } 

字节代码:

 Classfile /E:/Test.class Last modified Oct 9, 2015; size 265 bytes MD5 checksum fd115be769ec6ef7995e4c84f7597d67 Compiled from "Test.java" public class Test SourceFile: "Test.java" minor version: 0 major version: 51 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #4.#13 // java/lang/Object."":()V #2 = Integer 60000 #3 = Class #14 // Test #4 = Class #15 // java/lang/Object #5 = Utf8  #6 = Utf8 ()V #7 = Utf8 Code #8 = Utf8 LineNumberTable #9 = Utf8 main #10 = Utf8 ([Ljava/lang/String;)V #11 = Utf8 SourceFile #12 = Utf8 Test.java #13 = NameAndType #5:#6 // "":()V #14 = Utf8 Test #15 = Utf8 java/lang/Object { public Test(); flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."":()V 4: return LineNumberTable: line 1: 0 public static void main(java.lang.String[]); flags: ACC_PUBLIC, ACC_STATIC Code: stack=1, locals=2, args_size=1 0: ldc #2 // int 60000 2: istore_1 3: return LineNumberTable: line 3: 0 line 4: 3 } 

在编译时。 这是最基本的编译器优化之一,称为常量折叠 。

只需创建类Test

 public class Test { public static void main(String [] args) { long timeInMilliseconds = System.currentTimeMillis(); double timeInMinutes = (double) timeInMilliseconds / (1000 * 60); System.out.println(timeInMinutes); } } 

并使用命令对其进行反编译: javap -v Test

你可以看到反编译类的输出:

  public static void main(java.lang.String[]); flags: ACC_PUBLIC, ACC_STATIC Code: stack=4, locals=5, args_size=1 0: invokestatic #2 // Method java/lang/System.currentTimeMillis:()J 3: lstore_1 4: lload_1 5: l2d 6: ldc2_w #3 // double 60000.0d 9: ddiv 10: dstore_3 11: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream; 14: dload_3 15: invokevirtual #6 // Method java/io/PrintStream.println:(D)V 18: return LineNumberTable: line 3: 0 line 4: 4 line 5: 11 line 6: 18 

看看第6行: ldc2_w#3 //双60000.0d