Search code examples
javaconstructor-overloadingconstructor-chaining

Chaining Constructors in Java


Could not came up with better title.

A classic learning example: class Human, where properties are name, age, mother and father. Both parents are Human as well.

public class Human {
    String name;
    int age;
    Human mother;
}

I want to create 3 constructors:

  1. Human();
  2. Human(String name, int age);
  3. Human(String name, int age, Human mother).

I guess I do understand how the chaining works, and that's what I did:

Human() {
    this("Jack", 22);
}

Human(int age, String name) {
    this(age, name, new Human()); // new Human() will cause SOF Error.
}

Human(int age, String name, Human mother) {
    this.age = age;
    this.name = name;
    this.mother = mother;
}

As mentioned above, I receive StackOverflowError, once again I guess I know why it happened. Although to be fair I thought I will get something like Human Jack where his mother is also Human Jack.

Nevertheless, I wonder how should it be done. My guess is that instead of new Human() I should call the constructor with all parameters, but I'm not sure if it's true and the only option available.

Will appreciate any guidance here.


Solution

  • Yes, you're right about why it happens. Just to be sure, though:

    • new Human() calls this("Jack", 22)
    • this("Jack", 22) calls this(age, name, new Human())
    • The new Human() in that calls this("Jack", 22) again
    • which calls this(age, name, new Human()) again
    • until you run out of stack

    The right way to do it is to ensure that you don't end up back where you started. So if you use new Human(String) or new Human(String, int) in any of your constructors, you have to be sure that that constructor (new Human(String) or new Human(String, int)) doesn't also use new Human(String) or new Human(String, int), since you'll end up endlessly recursing. You need to use new Human(String, int, Human) somewhere. So for instance:

    Human(int age, String name) {
        this(age, name, null);
    }
    

    Of course, that means the new instance will have null for mother.