当前位置: 首页 > 知识库问答 >
问题:

请说明我的程序[副本]的执行顺序

万俟超
2023-03-14

我正在尝试理解代码的调用顺序。来人,请解释一下通话顺序。

public class MainWithStaticCalls
{
    static
    {
        String[] str = {"1", "2"};
        System.out.println("Static");
        main(str);
    }
    {
        System.out.println("Init block");
    }
    void MainWithStaticCalls()
    {
        System.out.println("constructor");
    }
    public static void main(String[] a)
    {
        MainWithStaticCalls obj = new MainWithStaticCalls();
        NewClass nc = new NewClass();
        nc.callMe();
        System.out.println("Main");
    }

}

class NewClass
{
    public void callMe()
    {
        System.out.println("I'm called");
    }
}

根据我的理解,静态块将在JVM开始执行时立即执行,甚至在main类之前执行。然后执行实例初始化块。则应执行构造函数。但如果我们从静态字段调用main方法,回调是如何工作的。以及哪个main将首先被执行,哪个JVM正常执行,哪个static字段显式调用。

My output:
Static
Init block
I'm called
Main
Init block
I'm called
Main

附注:我修改了我的问题。前面我把普通方法和构造函数混淆了,所以一些答案看起来可能不相关,但这确实帮助我理解了这个问题。

共有2个答案

秦新立
2023-03-14

类中没有定义构造函数,因此调用默认构造函数。

void MainWithStaticCalls()

不是构造函数。这是方法,因为构造函数没有返回类型。

明星剑
2023-03-14

我将尝试用一个示例来解释调用序列,但首先让我们考虑一下,如果您添加void访问限定符,这将是一个方法而不是构造函数。

其次,请记住,一个类可以有两种类型初始化块:

  • 静态初始化块
  • 实例初始化块

静态初始化块将首先在构造函数之前被调用,因为它是类级别的,甚至在创建任何类实例(即该类类型的对象)之前就会被执行。第二个,即在创建类的新实例时立即执行实例初始化块。在这两个块之后,它将被称为构造函数。您可以通过以下示例看到它:

public class MainWithStaticCalls {

    {
        System.out.println("Init block called");
    }

    static {
        String[] str = {"1", "2"};
        System.out.println("Static called");
    }

    public MainWithStaticCalls() {
        System.out.println("this is constructor");
    }

    void MainWithStaticCalls() {
        System.out.println("this is NOT constructor");
    }

    public static void nope() {
        System.out.println("Nope");
    }

    public static void main(String[] a) {
        MainWithStaticCalls.nope();
        System.out.println("************");
        MainWithStaticCalls obj = new MainWithStaticCalls();
        NewClass nc = new NewClass();
        nc.callMe();
        System.out.println("Main");
    }

}

输出为:

Static called
************
Init block called
this is constructor
NewClass: I'm called
Main

如果注释掉“nope”静态调用:

public class MainWithStaticCalls {

   ... // Same thing as above

    public static void main(String[] a) {
        // MainWithStaticCalls.nope();
        System.out.println("************");
        MainWithStaticCalls obj = new MainWithStaticCalls();
        NewClass nc = new NewClass();
        nc.callMe();
        System.out.println("Main");
    }

}

结果是:

Static called
************
Init block called
this is constructor
NewClass: I'm called
Main

因此,如果不注释掉“nope”调用,结果是相同的。这是为了说明静态方法只被调用一次,当类第一次被JVM面对时。如果我们实例化另一个对象:

public class MainWithStaticCalls {

   ... // Same thing as above

    public static void main(String[] a) {
        // MainWithStaticCalls.nope();
        System.out.println("************");
        MainWithStaticCalls obj1 = new MainWithStaticCalls();
        MainWithStaticCalls obj2 = new MainWithStaticCalls();
        NewClass nc = new NewClass();
        nc.callMe();
        System.out.println("Main");
    }

}

输出为:

Static called
************
Init block called
this is constructor
Init block called
this is constructor
NewClass: I'm called
Main

您可以看到,每次创建该类类型的新对象时(以及构造函数)都会调用实例初始化块,而静态初始化块只调用一次。

 类似资料:
  • 我实现了以下promise函数,比如 cart.getbasket(req) Cart.UpdateBasket(req) Cart.UpdateDefaultShipport(req) cart.GetBasketObject(basket) 当前我执行代码时使用 我读过关于的文章,并想把它用作逻辑的流程,但当我使用时,它并不像预期的那样工作,因为我看到each的

  • 此程序成功编译并显示以下输出。 问题 a)我不明白为什么alpha的构造函数没有首先被执行。 我相信“super()”会首先被每个子构造函数隐式调用...对吗?。 b)如果beta的构造函数已经执行,那么为什么打印“5”?(输出中的第二行) 第三行我有点理解(即alpha自己的变量将显示出来,因为还没有对“a”实例变量进行强制转换)

  • 本文向大家介绍vue.js页面加载执行created,mounted的先后顺序说明,包括了vue.js页面加载执行created,mounted的先后顺序说明的使用技巧和注意事项,需要的朋友参考一下 created页面加载未渲染html之前执行。 mounted渲染html后再执行。 由于created在html模板生产之前所以无法对Dom进行操作而mounted可以。 补充知识:关于Vue子组件

  • 本文向大家介绍请说说koa的app.use()执行流程相关面试题,主要包含被问及请说说koa的app.use()执行流程时的应答技巧和注意事项,需要的朋友参考一下 ,简单说其实就是把函数存放到数组里,然后返回实例对象。 中详细点,则是判断是generator函数,用(其实用的是)转换一次,再存放到数组里。 真正执行是。 具体源码可以看我这篇文章。 若川:学习 koa 源码的整体架构,浅析koa洋葱

  • 问题内容: 我尝试从一本书(Paul Hyde,Java Thread Programming)中运行示例。它说线程的顺序将互换。但是我总是得到:之后打印10个“主线程”,然后打印10个“新线程”。更有趣的是:如果我将使用tt.run而不是tt.start,那么结果将相反。也许这本书太老了,示例基于JDK 1.2的原因???代码如下: 问题答案: JVM决定何时将控制权从主线程转移到第二个线程。由

  • 本文向大家介绍Unity3D中脚本的执行顺序和编译顺序,包括了Unity3D中脚本的执行顺序和编译顺序的使用技巧和注意事项,需要的朋友参考一下 事件函数的执行顺序 先说一下执行顺序吧。 官方给出的脚本中事件函数的执行顺序如下图: 我们可以做一个小实验来测试一下: 在Hierarchy视图中创建三个游戏对象,在Project视图中创建三条脚本,如下图所示,然后按照顺序将脚本绑定到对应的游戏对象上: