繁体   English   中英

Java静态初始化行为

[英]Java static initialization behaviour

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初始化时。 请解释原因。

静态块按顺序执行。

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

只有在这之后i = 5

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

在创建Hello对象时,初始化非静态变量ij

public static final Hello h = new Hello();

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

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

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

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

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

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

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

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

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);
        }
    }

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

public static final Hello h = new Hello();

and default value of when the class is loaded. 在加载类时,创建一个且默认值为的对象。

and non static members, both will have default values for the . 如果同时使变量非静态成员,则两者都将具有默认值。

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

Hello helloObj = new Hello();

它会给你想要的结果。

来自oracle规范的文档

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM