代码之家  ›  专栏  ›  技术社区  ›  batman

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

  •  10
  • batman  · 技术社区  · 9 年前

    我正在努力理解java字节码。我从一个简单的例子开始:

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

    我编译了这个类:

    javac Test.java
    

    然后我试着 javap 在.class上,如下所示:

    javap -c Test
    

    这给了我:

    Compiled from "Test.java"
    public class Test {
      public Test();
        Code:
           0: aload_0       
           1: invokespecial #1                  // Method java/lang/Object."<init>":()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上之前?如果是,怎么办?

    1 回复  |  直到 9 年前
        1
  •  25
  •   Community gkalpak    4 年前

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

    请参见 Java Language Specification ,上面写着:

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

    看见 this other chapter 对于构成常量表达式的内容

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

    • 原始类型的文本和String[…]类型的文本
    • 加法运算符+和- [...]