15

I encountered a question that asks "Which of the following are true about the "default" constructor?"

and an option "It initializes the instance members of the class." was incorrect choice.

Now my understanding was that if we have a code such as

    Class Test {
        String name;
    }

then the compiler creates default constructor that looks like

    Class Test {
        String name;
        Test(){
            super();
            name = null;
        }
    }

Isn't the default constructor initializing the instance member name=null ?

SERich
  • 553
  • 2
  • 4
  • 13

7 Answers7

13

The class constructor is not the one doing the initialization, the JVM does this.

After memory for the object is allocated, the members of the object are default initialized to some predictable value, which becomes their default value. This is all done before the constructor is called!

According to the specification

  • Each class variable, instance variable, or array component is initialized with a default value when it is created (§15.9, §15.10.2):
  • For type byte, the default value is zero, that is, the value of (byte)0.
  • For type short, the default value is zero, that is, the value of (short)0.
  • For type int, the default value is zero, that is, 0.
  • For type long, the default value is zero, that is, 0L.
  • For type float, the default value is positive zero, that is, 0.0f.
  • For type double, the default value is positive zero, that is, 0.0d.
  • For type char, the default value is the null character, that is, '\u0000'.
  • For type boolean, the default value is false.
  • For all reference types (§4.3), the default value is null.

Your assumption is close but the fact is, before the constructor parameters are even evaluated, before it can even assign a value to each of the fields - those fields already hold their default values, and this is done by the JVM.

Read subsection §15.9.4 to understand how the initialization process is carried out

smac89
  • 39,374
  • 15
  • 132
  • 179
  • Does that imply that for well-written non-default constructors, your members are initialised then immediately their value changes again? Doesn't seem very efficient. – Lightness Races in Orbit Jul 27 '16 at 12:08
  • @LightnessRacesinOrbit It is not always the case that all non-default constructors will initialise all members. _Well written_ is a fun property to try and evaluate. – Gusdor Jul 27 '16 at 12:56
  • @LightnessRacesinOrbit: I've only contributed to one Java implementation, and that was many years ago, but the way we did it was to allocate zero-ed memory (and IIRC the gc zeroed memory on destruction). So yes, in some sense that is inefficient compared with C or C++, where there's such a thing as uninitialized memory. What you're paying for, is that there's no such thing in Java. But it's not so bad as explicitly assigning `0` to a `byte` data member that's about to be overwritten. It was all `memset`-like, normally in low priority threads. I don't know whether Oracle does it the same way. – Steve Jessop Jul 27 '16 at 14:10
  • 1
    Anyway my point is just that "after memory for the object is created, the members of the object are default initialized" is a nominal, "as-if" description of the requirement. – Steve Jessop Jul 27 '16 at 14:18
4

In Java fields are initialized before the constructor. This can be easily proved by the following code:

public class MyClass {

    int myField = initMyField();

    MyClass(){
        System.out.println("ctor");
    }

    static int initMyField() {
        System.out.println("init field");
        return 1;
    }
}

output

init field
ctor

You can also check the de-compiled code.

Cheng Chen
  • 42,509
  • 16
  • 113
  • 174
  • 2
    -1 this doesn't prove anything. As the implicit `super()` the initialization could be weaved in, at the start of the constructor. – Angelo.Hannes Jul 27 '16 at 11:25
  • You are actually showing a different thing: The initialization you show is actually moved into an initialization block of the class, where it is executed after the initial 0 initialization of all parameters (which is done by the JVM after allocating memory for the object) and after these two are done the constructor is called. – Falco Jul 27 '16 at 11:32
  • `myField`, `initMyField`. Note the lowerCase. – glglgl Jul 27 '16 at 12:09
  • If you turn your `[iI]nitMyField` onto an instance method, you can make it show that `this.myField` os actually 0 before setting it. – glglgl Jul 27 '16 at 12:10
3

Isn't the default constructor initializing the instance member name = null?

No, constructors get called after all instance variables are initialized by the default values: 0 or the equivalent value for primitive numerical types, false for the boolean type, null for reference types.

Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
1

No, it is not the default constructor which initialize the instance variables for you. Each type has a default value. The moment you created the object, the default value is used.

So if you do not explicitly initialize the instance variables, they will be still using the default values defined for them implicitly.

i.e. 0 for int, null for reference type.. etc

However, it is worth noting that we should not take it for granted that a default value is given, and choose not to initialize the variables.


You may try defining an empty constructor which override the default constructor with empty implementation. You will realize all instance variables will still be initialized.

user3437460
  • 17,253
  • 15
  • 58
  • 106
1

It does. Although the question is based more on usage.

public class Main {
    String x;

    Main() {
        x = "Init";
    }

    @Override
    public String toString() {
        return x;

    }

    public static void main(String[] args) {
        System.out.println(new Main());
    }

}

Ouput:

Init
RCInd
  • 344
  • 2
  • 13
1

Whenever we are executing a java class, first Static Control Flow will be executed. In the Static Control Flow if we are creating an object then the following steps will be executed(in the mentioned order) as a part of Inatance Control Flow:

  1. Identification of instance members(instance variable and instance blocks) from top to bottom.
  2. Execution of instance variable assignments and instance blocks.
  3. Execution of constructor.

So, in your above code the instance variable "name" is already assigned to null(default value for reference types) even before the constuctor is executed.

0

Default constructor provides the default values to the object (s) and is normally created by the compiler when no constructor is explicitly defined. e.g.

class DefaultTest{  
int id;  
String name;  

void display(){System.out.println(id+" "+name);}  

public static void main(String args[]){  
DefaultTest s1=new DefaultTest();  
DefaultTest s2=new DefaultTest();  
s1.display();  
s2.display();  
}  
}  

NB: There being no constructor defined the compiler will generate a default constructor that will assign 0 null values to the two objects.

mc.Ambugo
  • 1
  • 1