Java编译器如何决定静态和实例成员/块的执行优先级

问题描述 投票:2回答:4
public class Test {
    public static void main(String str[]) {
        Hello h=Hello.INS1;
    }
}

class Hello {
 static Hello INS1=new Hello();
 static Hello INS2=new Hello(12);
{
    System.out.println("Instance Block");
}
static {
        System.out.println("Static Block");
}
private Hello() {
    System.out.println("Hello() Block");
}
private Hello(int ab) {
    System.out.println("Hello() Block");
}
}

总是首先执行一个静态块,但是这段代码给出了一些我无法在脑中钉住的东西。这里到底发生了什么......?

OUTPUT:实例块Hello()块实例块Hello()块静态块

java compiler-construction static-members
4个回答
4
投票

当类加载到JVM中时执行静态块,并在创建对象时执行实例块。

可以存在多个静态和实例初始化块,它们自身的执行顺序将按其从上到下的顺序排列。

例如,考虑以下代码。

public class InitBlockExample{
    {
       System.out.println("X");
    }
    {
       System.out.println("Y");
    }
    static{
       System.out.println("A");
    }
    static{
       System.out.println("B");
    }
}

创建此类的对象时(要显示静态和实例块对象创建是必要的),输出将如下所示: -

一个 乙 X ÿ

静态语句也与静态块一起参与顺序执行,首先执行首先执行的那些,这个问题适用于你的问题,你创建的类变量是静态的,所以它们将首先被执行,因为它们需要构造函数执行首先执行构造函数但在构造函数之前执行所有实例初始化块,因此首先执行它们然后执行构造函数,最后执行静态块。如果你放

static Hello INS1=new Hello();
static Hello INS2=new Hello(12);

在静态块之后,输出将被反转,并且将首先执行静态块。


0
投票

始终首先执行静态块,但仅在实例块之后执行,

这是错误的。反过来也是如此。

加载类时将执行静态块,仅执行一次。

实例块将在实例创建后执行。 Java编译器将初始化程序块复制到每个构造函数中。


0
投票

Static不需要任何对象来执行。在创建任何对象之前,静态块可以像我们在静态方法中使用一样执行。因此,这里静态块是在JVM执行时调用的,意味着在创建对象之前(第一次执行JVM时)。但是每次创建对象时都会调用/加载初始化块。无论何时创建对象,都会加载初始化块。

Reference post.


0
投票
class Parent2
{

    static   //static block of parent
    {
        System.out.println("im in parent staic block");
    }

    {    //instance block of parent
            System.out.println("im in parent instance block");
    }

    public Parent2() 
    {
        System.out.println("im in Parent constructor");
    }
}

class Child2 extends Parent2
{
    static  //static block of child
    {
        System.out.println("im in child staic block");
    }

    {   //instance block of child
        System.out.println("im in child instance block");

    }
    public Child2() 
    {
        System.out.println("im in child constructor");

    }

}
public class ExePriorities
{
    public static void main(String[] args)
    {
        System.out.println("im in main and create 1st object");
        Parent2 c1=new Child2();
        System.out.println();
        System.out.println("************create 2nd object********************");
        System.out.println();
        Parent2 c2=new Child2();
    }

}

  [![output of above java code ][1]][1]
© www.soinside.com 2019 - 2024. All rights reserved.