HelloWorld程序为JVM代码

时间:2016-10-12 10:30:09

标签: java jvm

让我们考虑以下代码:

package p;
public class Simple {

public static void main(String[] args){
    System.out.println("HELLO!\n");
   }
}

和它的JVM代码(javap -c Simple.class):

Compiled from "Simple.java"

public class p.Simple {
  public p.Simple();
    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: ldc           #3                  // String HELLO!\n
       5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: return
}

我有一个问题:

  1. 可能,入口点是main函数。但是,在此之前,调用Simple类的构造函数是必要的。 那么它是怎样工作的?我的意思是,谁首先调用构造函数然后将控件传递给main? 如果我错了,请向我解释控制流程的工作原理。

  2. getstatic之类的说明会使用#2之类的参数。这是什么意思#2

  3. 评论如下:// Method java/lang/Object."<init>":()V 这是什么意思V

  4. 控制流程如何运作?

2 个答案:

答案 0 :(得分:2)

  1. 当没有显式定义时,Java编译器会自动生成构造函数。在你的例子中,它根本没有被调用。它只是自动生成政策。
  2. 它是PrintStreamout属性System的引用。 Java编译器自动将import语句转换为完全限定的对象声明。
  3. V表示void
  4. 可能是这样的:
    1. 加载参考。
    2. 使用该值创建一个匿名String对象。
    3. 将堆栈框架推到适当位置,并参考#2作为参数跳转到println方法的入口点。
  5. #2意味着什么:

    import java.util.List;
    
    List x;
    

    变得简单:

    java.util.List x = new java.util.ArrayList();
    

    当编译器生成字节码时。 java.lang会自动导入。

答案 1 :(得分:0)

  1. 在这种情况下不调用构造函数,因为main()是静态的。

  2. getstatic获取System.out静态字段的值

  3. V表示void,即main()返回类型为void