Java静态初始化行为

时间:2013-06-21 11:23:35

标签: java static

public class Hello {
        public static final Hello h = new Hello();
        static int i = 5;
        int j  = i;

        private void print() {
            System.out.println(i+" , "+j);

        }
        public static void main(String[] args) {

            h.print();
        }

    }

此代码输出为5,0。 如果原因是静态加载在类中,我初始化并且j不是。但如果我从i中删除静态

public class Hello {
        public static final Hello h = new Hello();
        int i = 5;
        int j  = i;

        private void print() {
            System.out.println(i+" , "+j);

        }
        public static void main(String[] args) {

            h.print();
        }

    }

现在为什么输出是5,5。然后当i和j初始化时。 请解释原因。

7 个答案:

答案 0 :(得分:16)

静态块按顺序执行。

首先创建一个Hello对象,此时i = 0尚未设置。

此后才i = 5

您必须从上到下阅读静态语句。

答案 1 :(得分:5)

在创建i对象的那一刻,非静态变量jHello被初始化:

public static final Hello h = new Hello();

问题的第一部分Peter给了你一个答案。让我补充一下。如果您更改了静态变量的顺序:

static int i = 5;
public static final Hello h = new Hello();
int j  = i;

它会打印5, 5而不是5, 0

答案 2 :(得分:2)

尝试交换public static final Hello h = new Hello();static int i = 5;行。 您首先初始化hello对象(when i = 0, uninitialized)而不是i。首先启动i以获得预期的行为。

答案 3 :(得分:2)

以下是您的第一个示例中发生的事情:

  • 静态内存初始化为0.此时Hello.i等于0.
  • Hello.h被实例化:
    • Hello.h.j初始化为Hello.i的当前值,即0。
  • Hello.i初始化为5。

在你的第二个例子中,另一方面:

  • Hello.h被实例化:
    • Hello.h.i初始化为5。
    • Hello.h.j初始化为Hello.h.i的当前值,即5。

答案 4 :(得分:1)

Peter Lawrey的回答是正确的,你的困惑可能来自于一切都属于单一类的事实,名字就是这样,所以我想给你另一种方式来形象化你的行为,所以你的代码在逻辑上等同于以下代码:

public class Program {

    public static Hello h = new Hello();

        public static void main(String [] args) {
            h.i = 5;
            h.print();
        }
    }

    class Hello {

        public static int i = 0;
        private int j = i;

        public void print() {
            System.out.println(i+", "+j);
        }
    }

答案 5 :(得分:0)

Java在类加载时执行静态初始化。因此

public static final Hello h = new Hello();

在加载 Hello 类时,创建一个 i = 5 且默认值为 j 的对象。

如果同时设置变量 i j 非静态成员,则两者都将具有静态对象h 的默认值。

如果在main方法中创建一个新对象

Hello helloObj = new Hello();

它会给你想要的结果。

答案 6 :(得分:0)

From docs of oracle specs

  

在类初始化时执行类中声明的静态初始化程序(第12.4.2节)。与类变量的任何字段初始值设定项(第8.3.2节)一起,静态初始值设定项可用于初始化类的类变量。