Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Default Initialization of Private Fields in Java

Tags:

java

Say I have a class called Person:

class Person{
    private int num = 1;
}

When calling the empty constructor for class Person, will Java first initialize num to a default value of zero, and then assign num to 1? Or will Java initialize num to 1 straight away? Doesn't C++ do the former unless you use initializer syntax?

Thank You!

like image 548
E. Kaufman Avatar asked Dec 10 '22 06:12

E. Kaufman


1 Answers

It would assign the value zero first.

If you put something before the field declaration like so, you could see this:

class Person{
    { print(); }
    private int num = 1;
    { print(); }

    void print() {
      System.out.println(num);
    }
}

This would print:

0
1

This is described in JLS Sec 4.12.5:

Each class variable, instance variable, or array component is initialized with a default value when it is created 

And Sec 15.9.4 (emphasis added and some parts omitted):

The new object contains new instances of all the fields declared in the specified class type and all its superclasses. As each new field instance is created, it is initialized to its default value (§4.12.5).

...

Next, the selected constructor of the specified class type is invoked ...

In other words, object creation and constructor invocation are distinct operations, and the fields are initialized to their default values prior to the invocation of the constructor.

The actual field initialization occurs in the constructor: field initializes are inlined into every constructor that invokes super(...), immediately after the call to super(...). The following is exactly equivalent to the above:

 class Person{
   private int num;

   Person() {
     super();
     print();
     num = 1;
     print();
   }

   void print() {
     System.out.println(num);
   }
}

One subtle point to make it that although declaring the field final would make the output of this code:

1
1

This does not mean that final variables are initialized sooner. All that has changed in that case is that num has become a compile-time constant expression, and thus is inlined. As such, print() would actually be executing:

System.out.println(1);

In other words, it does not read the field at all.

like image 190
Andy Turner Avatar answered Mar 01 '23 15:03

Andy Turner