Constructors

index
BASIC

A constructor is a bit of code that allows you to create objects from a class. You call the constructor by using the keyword new, followed by the name of the class, followed by any necessary parameters. For example, if you have a Dog class, you can create new objects of this type by saying new Dog().

The syntax for a constructor is:

access NameOfClass(parameters) {
        initialization code
    }

where

The term "constructor" is misleading since, as soon as you enter the constructor, the new object has actually been created for you. The job of the constructor is to ensure that the new object is in a valid state, usually by giving initial values to the instance variables of the object. So a "constructor" should really be called an "initializer."

Every class has at least one constructor. There are two cases:

  1. If you do not write a constructor for a class, Java generates one for you. This generated constructor is called a default constructor. It's not visible in your code, but it's there just the same. If you could see it, it would look like this (for the class Dog):
         public Dog() { }
    Notice that this default constructor takes no arguments and has a body that does nothing.
  2. If you do write a constructor for your class, Java does not generate a default constructor. This could be a problem if you have pre-existing code that uses the default constructor.
Note: Some textbooks refer to any no-argument constructor as a "default constructor." This is wrong. The default constructor is the one Java provides by default. Anything you write explicitly is not a default.

Example constructors:

class Dog extends Animal {
    String name;
    String breed;
  
    // first constructor
    public Dog(String s) {
        name = s;
        breed = "unknown";
    }
 
    // second constructor
    public Dog(String name, String breed) {
        this.name = name;
        this.breed = breed;
    }
}

To avoid having to use different names for the same thing, the second constructor uses a simple trick. The parameter names are the same as the names of some instance variables; to distinguish the two, this.variable refers to the instance variable, while variable refers to the parameter. This naming convention is very commonly used.

INTERMEDIATE

It is poor style to do the same work in more than one place. Hence, if you have more than one constructor, it is common for one to do most of the work, and for others to just call that one.

To call one constructor from another in the same class, you use the syntax this(parameters); -- this must be the first thing you do in the constructor. For example, you might rewrite the first Dog constructor above to call the second Dog constructor, as follows:

// first constructor
public Dog(String name) {
    this(name,"unknown");
    // additional code, if needed, can go here
}

Unless a constructor begins by explicitly calling some other constructor, the first thing it does is to call the default constructor for its superclass. Hence, if class Dog extends Animal, and class Animal extends LivingThing, and class LivingThing extends Object , then when you create a new Dog,

  1. The Dog constructor calls the Animal constructor,
  2. The Animal constructor calls the LivingThing constructor,
  3. The LivingThing constructor calls the Object constructor,
  4. The Object constructor creates a new Object, with all the fields and methods of an Object, and returns it to the LivingThing constructor,
  5. The LivingThing constructor adds to this Object the fields and methods of a LivingThing, gives them initial values, and returns this new LivingThing to the Animal constructor,
  6. The Animal constructor adds to this LivingThing the fields and methods of a Animal, gives them initial values, and returns the new Animal to the Dog constructor,
  7. The Dog constructor can now do any further desired initialization.

It is important to notice that unless you explicitly say otherwise, a constructor calls the default constructor for its superclass. You can use this(parameters); to call some other constructor in the same class, or you can use super(parameters); to explicitly call some particular constructor in the superclass.

ADVANCED

Whenever a constructor is called, an object of that class will be created. If you want more control over when objects may be created, you can declare your constructors to be private. To get to the constructor, you would call a static method within the class, and this static method can then decide what to do about the request for a new object. For example:

class Controlled {
    private Controlled(args) {
        ...
    }
    public static Controlled create(args) {
        if (/* some conditions */) return new Controlled(args);
        else return null;
    }
}

Such a method is called a factory method.