Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it good or bad to delegate to another constructor (using this()) within a constructor

Oracle reference doesn't tell about best practice of this keyword while we overload constructors. Can anyone suggest the best practice for it?

Option 1: delegate to another constructor

public class A {
    private int x, y, z, p;  

    public A() {
        this(1,1,1,1);
    }

    public A(int x, int y, int z, int p) {
        this.x = x;
        this.y = y;
        this.z = z;
        this.p = p;
    }
}

and

Option 2: set each field rather than delegating

public class A {
    private int x, y, z, p;  

    public A() {
        this.x = 1;
        this.y = 1;
        this.z = 1;
        this.p = 1;
    }

    public A(int x, int y, int z, int p) {
        this.x = x;
        this.y = y;
        this.z = z;
        this.p = p;
    }
}
like image 283
instinct Avatar asked Dec 26 '22 07:12

instinct


2 Answers

The first one is the best.

It is referenced multiple times in the offical docs and in many books. It is a specific case of method-chaining or, as others noted in the comments, telescoping constructors. They allows you to write less code and to not repeat yourself (DRY).

You can find that approach everywhere in solid libraries like Apache Commons and also in the best practices of other platforms. Finally, the famous book Thinking in Java, use this form in the Initialization & Cleanup chapter (Calling constructors from constructors section).

like image 88
mxb Avatar answered Dec 28 '22 06:12

mxb


The first sample is preferable, this is called constructor-telescoping or constructor-chaining. Following this pattern the primary constructor (which takes a parameter for each field that can be set) can be called by secondary constructors that set defaults.

In the first example there is only one place where the instance variable is assigned, while in the second example both constructors have to know which instance variable to use, so the first one has less cut-n-paste duplication.

In addition, this way initialization proceeds in a single consistent path rather than allowing totally different ways to initialize the object, where initialization results could differ depending on which constructor was called. This way any code added to the primary constructor will always be called.

I borrowed the terms "primary constructor" and "secondary constructor" from Scala. In Scala this style is enforced by the language, option 2 is not allowed.

like image 40
Nathan Hughes Avatar answered Dec 28 '22 05:12

Nathan Hughes