5

If a class need multiple field information during object creation and also it is allowing fewer information.Than we have two option
1. Provide multiple constructor, or
2. Allow client to pass null argument while creating object.

Among these which is the best practice. ex:
Case-1:

public class Test {
    Test(A ob1,B ob2, C ob3){

    }
    Test(A ob1,B ob2){
            this(ob1, ob2, null);    
    }
    public static void main(String args[]){
        Test ob = new Test(new A(),new B());
    }
}

Case-2:

public class Test {
    Test(A ob1,B ob2, C ob3){

    }
    public static void main(String args[]){
        Test ob = new Test(new A(),new B(), null);
    }
}

I have used main method in same class. Please consider these main methods in some other class.

Hardik Mishra
  • 14,779
  • 9
  • 61
  • 96
shantanu
  • 1,748
  • 3
  • 19
  • 34

5 Answers5

9

Using multiple constructors is the best. Many standard API libraries also have implemented it. Also It makes code loosely coupled and not a good practice to create the object by passing explicit 'null' value.

Case 2 increases chances of High coupling.

Apart from main question : Read More: Best way to handle multiple constructors in Java

EDIT:

Its better practice to use named factory methods to construct objects as they're more self-documenting than having multiple constructors. [Effective Java by Joshua Bloch]

Hardik Mishra
  • 14,779
  • 9
  • 61
  • 96
  • The statement about usage of the constructor chaining is true for most API. But i can recall when i last saw passing a `null` in some of those API. If a object can be constructed without some value, generally is should not be part of constructor. – Damian Leszczyński - Vash May 16 '12 at 09:40
1

Case one is to prefer. This is done in most classes in the API that has this option. It also means that you can change the second/third/... argument in future releases if needed without having to upgrade the calls to the constructor.

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
Ludwig Magnusson
  • 13,964
  • 10
  • 38
  • 53
1

Case 3, provide a method that will create the object.

public class A {

  public static A create(B b) {
     A a = new A();
       a.setB(b);
  }

  public static A create(B b, C c) {
     A a = create(b);
       a.setC(c);

   return a;
  }

  private A() {} 

  public void setB(B);
  public void setC(C);

} 

The constructor should be able to crate the object to prevent memory leaks. Less parameters in it minimize the situation when NullPointerException will occur. Providing a factory method like presented would decrease that risk and improve the control over object.

  • Chances are that an `A` object *without* either a `B` or a `C` object is invalid. I'd rather have that an invalid `A` can not be created (even if it's only inside a factory method). – Joachim Sauer May 16 '12 at 07:16
  • how is this preferable to using constructors? – djna May 16 '12 at 07:34
  • @djna, That depend of the object that is created this way. In case when during creation something might go wrong it should be not initialized via constructor. If Constructor only assign references to members, then this solution should not be used. – Damian Leszczyński - Vash May 16 '12 at 09:34
  • @JoachimSauer, if I understood you properly, we may want to add some asserts before instance creation and as constructor of A is private it can not be accessed from other places so instance of A it can be created only via factory method. – Damian Leszczyński - Vash May 16 '12 at 09:36
  • @Vash If something can go wrong during construction we can throw an Exception. I see no difference in error handling possibilities in this "factory" case and normal constructor. I'm having trouble seeing advantage of the factory idiom. – djna May 16 '12 at 10:07
  • @djna, throwing exception from constructor is a problem is self. Generally speaking. Constructor should be designed in way that prevent fail during object creation to prevent memory leaks. Constructor that may fail are hard to mange in code and during tests. It is a lot to talk about this topic, please visit http://stackoverflow.com/questions/77639/when-is-it-right-for-a-constructor-to-throw-an-exception or other page where this topic is covered. – Damian Leszczyński - Vash May 16 '12 at 12:23
  • @Vash sorry, but I see no answers in that reference that commend the pattern you describe. The memory leak reference is to C++, which lacks garbage collection, throwing an exception from a constructor in Java will not leak memory. Constructor failing is no harder to manage than any other code failing, catch an exception at an appropriate level, do any extra tidy up in finally blocks ... how does your pattern avoid such work? – djna May 16 '12 at 13:24
  • @djna, The case is that having a `null` in constructor is not the best option and in this the idiom of factory method is better than cascade IMHO. About the leaks, i thought if object can not be constructed properly may provide to some leaks. If not i will verify this in some documentation. Nevertheless i still think that having a fatory method that prepare our object is better than contructor with null. My point is when we have A(String,Integer) we can write A("",null), but later we wan to add A(String,String) and then we will need to refactor all code. – Damian Leszczyński - Vash May 16 '12 at 13:41
  • So provide A(String) and A(String, Integer), that's exactly what you've proposed for the Factory. Precise signatures, no nulls. We're in danger of agreeing here ;-) – djna May 16 '12 at 15:18
  • Yes. We agree on that. But what I think that more likely coder will write A(String){super(String,null)} than a.setB(null). That is why i think in such cases, better approach is to use the factory idiom to create object. – Damian Leszczyński - Vash May 16 '12 at 15:50
0

The first case is the best one. Why would you want to avoid having multiple constructors? Unless you are not callig them, they do not bother you. Having different constructors also increases the readability of your code, because it is clear what parameters are needed to instantiate the object, in contrast to the null-case, where you always have to look what parameter is not needed.

htz
  • 1,037
  • 1
  • 13
  • 37
0

Nulls are not typed, hence you create potential for future errors and doubt

 new Thing( myA, null, null)

it's not clear here that the intent is to pass a null B and a null C,

 new Thing (myA)

is unambiguous

djna
  • 54,992
  • 14
  • 74
  • 117
  • In this case I can always typecast Null. – shantanu May 16 '12 at 07:49
  • @shantanu, you **can** but there is no compulsion to do so, so you, or a less diligent person **will not** and then we get less maintainable code. The class author, by not providing separate constructors has given the client more work to do. – djna May 16 '12 at 07:52