二进制运算符执行何时在Java中执行?

我正在尝试理解java字节码。 我从简单的例子开始:

public class Test { public static void main(String args[]) { System.out.println(2 + 1); } } 

我编译了这个类:

 javac Test.java 

然后我尝试在.class上的javap像这样:

 javap -c Test 

这给了我这个:

 Compiled from "Test.java" public class Test { public Test(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."":()V 4: return public static void main(java.lang.String[]); Code: 0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 3: iconst_1 4: invokevirtual #3 // Method java/io/PrintStream.println:(I)V 7: return } 

除了这一行,我能够理解它:

 public static void main(java.lang.String[]); . . . 3: iconst_1 . . . 

看着我的源代码和这个字节代码,看起来像javac已经为这个语句做了额外的操作:

 2+1 

并要求jvm返回该常量。

如果我的理解错了,有人可以纠正我吗? javac是否在jvm上实际运行之前对+-*等进行编译操作? 如果是这样的话?

2 + 1是编译时常量表达式。 编译器本身在字节码中将其替换为3。

请参阅Java语言规范 ,其中说:

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

有关常量表达式的构成,请参见本章

常量表达式是表示基本类型的值的表达式或不突然完成的字符串,仅使用以下内容组成:

  • 原始类型的文字和String类型的文字[…]
  • 添加剂操作符+和 – […]