Java 当实例化自己的类时,编译器如何处理Main

Java 当实例化自己的类时,编译器如何处理Main,java,compiler-construction,static,jvm,main,Java,Compiler Construction,Static,Jvm,Main,编辑:如需澄清: 创建一个包含静态main的新类。在main方法期间实例化相同的类。当JVM在实例化时到达主方法代码行时,它会做什么 (JVM如何知道在while循环期间在以下代码中“跳过”static main()方法) 我这样问是因为我看不到将静态main放入要实例化的类中有任何好处,似乎最好只将静态main放入“启动器”类中,该类仅为启动应用程序而构建 让狗类感到困惑的是: public class Dog { private int height; public sta

编辑:如需澄清:

创建一个包含静态main的新类。在main方法期间实例化相同的类。当JVM在实例化时到达主方法代码行时,它会做什么

(JVM如何知道在while循环期间在以下代码中“跳过”static main()方法)

我这样问是因为我看不到将静态main放入要实例化的类中有任何好处,似乎最好只将静态main放入“启动器”类中,该类仅为启动应用程序而构建

让狗类感到困惑的是:

public class Dog {
    private int height;

    public static void main (String[] args) { // <---- What does the JVM do when it reaches here during the object instantiation?
        int i = 0;
        Dog [] dogArray = new Dog[20];
        while (i < 20){
             dogArray[i] = new Dog(); // Instantiate knew class
             dogArray[i].height = i*10; //whatever
             i++;
        }
    }
}
公共级狗{
私人内部高度;
公共静态void main(字符串[]args){//
输出:

这是静态块

这是主要的

承包商是承包商

承包商是承包商

承包商是承包商

运行上面的代码,您将对此有更好的了解

运行程序时,jvm会调用
main
方法。为什么在实例化
Test
类时要调用它

当您实例化一个类时,首先将执行静态块。它将用于第一次实例化,而不是全部。(查看输出)

然后将调用构造函数


如果查看输出,则不会调用任何静态方法。只有在调用静态方法时才会调用它们。这就是为什么
count()在这种情况下,
不会执行。
main
方法被JVM调用一次,以启动程序,但是在那之后,它仍然是类的常规静态方法,不会超过调用它时的UTI。

结果是我在寻找的答案(以及我试图问的问题)JVM实际上是如何引导和调用main的。首先启动JVM的是本机代码,main方法是使用STATIC调用的,以避免以某种方式(外部)首先创建一个对象,然后从该对象调用main方法

我对主方法为何被“忽略”的困惑是对主方法调用方式的误解——它是由JVM在启动时显式调用的,这就是JAVA约定——JVM是以这种方式构建和设计的,它是一种专用方法

因此,在我的示例中,main作为一个方法,在main所属的类的每次实例化过程中都不会被调用(因为在实例化过程中不会隐式调用方法),我的印象是,每当类被实例化时,main都会自动被调用,因为它是“java主方法”-就好像它有一个要调用的钩子。关键在于掌握静态以及JVM如何加载主方法,而不首先实例化它的封闭类。这本质上是从JVM(包括本机)引导程序过程过渡到运行JAVA应用程序的更“纯”的面向对象功能


希望这是有意义的,希望它能帮助人们澄清一些事情。

你认为一个
main
方法是什么或是做什么的?你为什么这么认为?我认为这是JVM启动应用程序的目的——以及找到它后下一步该做什么。这就是为什么仅仅将main方法粘贴在一个具有其他函数的类中似乎是随机的从逻辑上讲,更清楚的是,OO应该给出它自己的“启动器”类,并将其他类保留为纯对象蓝图。你似乎觉得JVM只是执行它在一个类中找到的所有代码。Java不是这样工作的……它不“迭代”通过它。它加载符号表,然后调用表中的方法指向的代码。如果您想了解底层细节,只需阅读JVM规范;这真的不会比这更容易。这不仅仅是调用类的测试方法吗?如果您将类视为对象的蓝图,那么它就是在一个随机类中包含main会让人感觉很混乱。创建一个“类”来启动应用程序感觉更好,这样你就可以创建你的测试类并运行测试方法了。
Test()
这里是类
Test
构造函数
。无论你写不写,当你实例化一个对象时,它总是会被调用。是的,总是最好让拥有
main
的类单独存在,只用于调用和编写
POJO
类,并且把所有事情都做得干净利落。但是回答你的问题注意,对象创建不会调用
main
Thank,因此,如果该类碰巧包含main方法,JVM在实例化对象时会忽略main方法?它还会忽略其他任何内容吗?@LeonKowalski这里什么都不会忽略,为了证明这一点,只需使用一些静态方法创建一个类并实例化该类,您可以我看到静态方法不会被调用,就像
count()一样
我的代码中的方法。我很困惑,因为在我的示例中,在while循环中,当每个新的Dog对象被实例化时,JVM不会再次运行静态main方法-但是在第一次启动类时,它会运行。那么JVM如何确定何时使用main和何时不使用main?我在这里没有意义吗?
public class Dog {
    private int height;

    getHeight{//etc...}
    setHeight{//etc...}
}

public class launchApplication{
public static void main (String[] args) {
    int i = 0;
    Dog [] dogArray = new Dog[20];
    while (i < 20){
         dogArray[i] = new Dog(); // Instantiate knew class
         dogArray[i].setHeight = i*10; //whatever
         i++;
    }
}
public class Test {

    /**
     * The constructor
     */
    public Test() {
        System.out.println("The is the constrcutor");
    }

    /**
     * The main method
     * 
     * @param args
     */
    public static void main(String[] args) {
        System.out.println("This is main");

        new Test();
        new Test();
        new Test();
    }

    /**
     * A static method
     */
    public static void count() {
        System.out.println("This is a static method");
    }

    /**
     * A static block
     */
    static {
        System.out.println("This is the static block");
    }
}