1

In the code below, I have a User defined constructor (no arg constructor) and a parameterized constructor.

What I understand is that if I have at least one constructor, the compiler won't add a default/implicit constructor.

My Question:

In the main Method, I am creating Employee object by calling the parameterized constructor. In the parameterized constructor I am only setting the empId property.

When I try to print the value of name, it prints it as null (i.e. the default value).

What initializes name to NULL (i.e its default value)? It cannot be the implicit/default constructor generated by the compiler, since we have at least one constructor in the class.

public class Employee {

    String name;
    int empId;

    public Employee() {
        System.out.println("Calling User Defined Constructor");
    }

    @Override
    public String toString() {

        return "name=" + name + " empId=" + empId;

    }

    public Employee(String name, int empId) {
        this.empId = empId;
    }

    public static void main(String[] args) {

      Employee e = new Employee("test",123);

        System.out.println(e);
    }

}
4
  • The default values of fields are not assigned by any Java code; it's the VM which natively initializes an object's memory before even starting to execute constructors. If it wouldn't, one might be able to read spurious data from objects already gc'ed, which would be a security risk, especially for object references. Commented Dec 9, 2014 at 9:29
  • 'I am only setting the empId property' - How could you set empId value when there is no setter and getter? Commented Dec 9, 2014 at 9:36
  • this.empId = empId; :) Commented Dec 9, 2014 at 9:46
  • My assumption was that the variables are initialized to default values after any constructor call.So do yo mean that even before constructor is called ,VM defaults the instance variables to some value?? Commented Dec 9, 2014 at 10:11

5 Answers 5

2

Class variables of reference type have a default value of null (as opposed to local variables that don't have a default value). Similarly, class variables of primitive types have their own default values.

Your code is equivalent to :

public class Employee {

    String name = null;
    int empId = 0;
    ...
}
Sign up to request clarification or add additional context in comments.

2 Comments

My assumption was that it was constructor which initializes the variables to default values. From your explanation it seems VM initializes them to default before constructor call.Is it so?
@ankurlu That's correct. They are initialized before the constructor is executed. Of course, the constructor can change those default values.
0

JLS for the rescue, JLS 4.12.5. Initial Values of Variables:

For all reference types (§4.3), the default value is null.

And since String is a reference type, it gets null as default value:

ReferenceType:
    ClassOrInterfaceType
    TypeVariable
    ArrayType

Consider assigning it in your constructor:

public Employee(String name, int empId) {
    this.empId = empId;
    this.name = name;
}

Comments

0
public Employee(String name, int empId) {
    this.name = name; // You are missing this line
    this.empId = empId;
}

public static void main(String[] args)
{
    Employee e = new Employee("test",123);
    System.out.println(e);
}


String name in the Employee class is implicitly null when declared, i.e.

String name = null;


Any reference type variable (such as String in this case) is given a default value of null.

Variable initialization and default values

Comments

0

A constructor is executed as follows:

  • All fields are "zeroed"; null, 0, 0.0, '\u0000'
  • The super constructor is called, either explicitly of an implicit super();
  • All field initialisations happen; that is only those fields with = ....
  • The rest of the constructor code is executed.

You may find the following puzzle (what is printed?) enlightening.

class A {
    A() {
        terrible();
    }
    protected void terrible() {
        System.out.println("A.terrible - " + this);
    }

}

class C extends A {
    C() {
        System.out.println("C.terrible - " + this);
    }

    String a;
    String b = null;
    String c = "c";

    @Override
    protected void terrible() {
        System.out.println("C.terrible - " + this);
        a = "aa";
        b = "bb";
        c = "cc";
        System.out.println("C.terrible (2) - " + this);
    }

    @Override
    public String toString() {
        return String.format("a=%s, b=%s, c=%s", a, b, c);
    }
}

Comments

0
public Employee(String name, int empId) {

    this.empId = empId;
}


public Employee() {
    System.out.println("Calling User Defined Constructor");
}

Based on your Instance, the constructor will load at Run time.

Construtor is set the values while Initialize the object itself.

So in your case, only one instance is created.. It passed two values. but assigning only one value. So name is default set to be null.....

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.