简体   繁体   中英

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

    }

This code output is 5 , 0. if reason is static loads first in class and i is initialized and j is not.but if i remove static from i also

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

    }

now why output is 5,5. then when i and j is initialized. please explain the reason.

The static block is executed in order.

You first create a Hello object, at this point i = 0 as it hasn't been set.

Only after this does i = 5

You have to read the static statements from top to bottom.

Non-static variables i and j are initialized that moment when Hello object is created:

public static final Hello h = new Hello();

For the first part of the question Peter gave you an answer. Let me complement it. If you changed the order of static variables:

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

it would print 5, 5 and not 5, 0 .

Try to swap the public static final Hello h = new Hello(); and static int i = 5; lines. You initialize first the hello object (when i = 0, uninitialized) and than i . Init the i first to get an expected behavior.

Here's what happens in your first example:

  • Static memory is initialized to 0. At this point Hello.i equals 0.
  • Hello.h is instantiated:
    • Hello.hj is initialized to Hello.i 's current value, ie 0.
  • Hello.i is initialized to 5.

In your second example, on the other hand:

  • Hello.h is instantiated:
    • Hello.hi is initialized to 5.
    • Hello.hj is initialized to Hello.hi 's current value, ie 5.

Peter Lawrey's answer is correct, your confusion may be coming from the fact everything is in a single class and the names are like so i wanted to give you another way to visualize what your doing, so your code is logically equivalent to the following code:

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 does static initialization at the time of class loading. Therefore

public static final Hello h = new Hello();

creates an object with i = 5 and default value of j when the Hello class is loaded.

If you make both the variables i and j non static members, both will have default values for the static object h .

If you create aa new object in your main method

Hello helloObj = new Hello();

It will give your the result you want.

From docs of oracle specs

A static initializer declared in a class is executed when the class is initialized (§12.4.2). Together with any field initializers for class variables (§8.3.2), static initializers may be used to initialize the class variables of the class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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