简体   繁体   中英

When is mandatory to have a default constructor along with parameterized constructor in Java?

Many a time I have got an exception saying "the default constructor's implementation is missing". And many a times a parameterized constructor's definition alone does everything. I want to know under which conditions this happens.

The compiler doesn't ever enforce the existence of a default constructor. You can have any kind of constructor as you wish.

For some libraries or frameworks it might be necessary for a class to have a default constructor, but that is not enforced by the compiler.

The problem you might be seeing is if you have a class with a custom constructor and you don't have an implicit super() call in your constructor body. In that case the compiler will introduce a call to the super classes default constructor. If the super class doesn't have a default constructor then your class will fail to compile.

public class MyClass extends ClassWithNoDefaultConstructor
    public MyClass() {
        super(); //this call will be added by the compiler if you don't have any super call here
        // if the super class has no default constructor the above line will not compile
        // and removing it won't help either because the compiler will add that call
    }
}

AS Joachim Sauer said, its important/some times required to provide default constructor apart from your parametrized constructor when you are using frameworks like spring. Because if you want inject your class object through dependency injection in another class, then the class should have default constructor.

Otherwise your dependency injection will fail.

Its just one scenario where i encountered the importance of default constructor

It is not entirely clear whether you are talking about a runtime exception or a compilation error.

A runtime exception will only occur if your code (or some library code called by your code) attempts to use reflection to create an instance of some class, and accidentally tries to use a non-existent constructor. (And I doubt that the exception message would use the term "default constructor" ...)

A compilation error happens because you are explicitly or implicitly attempting to call a "no args" constructor that does not exist. There are three scenarios'

// case #1
new Foo();

// case #2
public Bar extends Foo {
  public Bar() {
    super();
  }
}

// case #3
public Bar extends Foo {
  public Bar() {
    // no explicit 'this' or 'super' call.
  }
}

The first two examples are pretty obviously invoking a no-args constructor.

The last example invokes the no-args constructor because if you don't have an explicit super or this "call" at the start of a constructor, the JLS says that a call to super() will occur ... in all cases apart from the constructor for Object .


Finally, you answer the question in the title:

When is mandatory to have a default constructor along with parameterized constructor in Java?

Strictly speaking, it is never mandatory to have a default constructor. It is mandatory to have a no args constructor (either explicitly declared, or default) ... only if it is explicitly or implicitly called.

(There could be libraries / frameworks that assume that your classes have no-args constructors, but that is beyond the scope of what we can answer. And besides, such an assumption will be so that instances can be created reflectively ... and I've covered that.)

In general this situation can be happen when instance of class is creating by reflection (for example while de-serializing). If your class is Serializable or instance of it can be created by reflection mechanism, you should define default constructor.

If there is no Constructor present in a class, one Default Constructor is added at Compile time.

If there is any one parametrized Constructor present in a class, Default Constructor will not be added at Compile time.

So if your program has any constructor containing parameters and no default constructor is specified then you will not be able to create object of that class using Default constructor.

Eg:

class A{

A(int a){}

}

A a = new A() -----> Error.

-------------------------------------------------------

class A{

A(int a){}

A(){}

}

A a = new A() -----> It will work.

-----------------------------------------------------------

class A{

}

A a = new A() -----> It will work.
  • case 1:
    If you don't write a constructor then default constructor will be added (by compiler) and you can create object using it. But if you write a parameterised constructor, and want to create object like

    ClassName ObjName = new ClassName();

    then you have to add default constructor manually.

  • case 2(Inheritances): If your childclass constructor do not make a
    explicit call to parentclass constructor (in first line itself), then compiler will do it for you.

    class ChildClass extends ParentClass{ ChildClass(){ //super() added by compiler. } }

    Now same thing,

    if no constructor in parentclass, fine Default Constructor (added by compiler) will be called.

    but if parentclass has a parameterised constructor, then there is no default constructor and so you get your error.

  • Its mandatory when you have a Parameterised constructor and

    1. want to create object like case 1.

    2. inherit this class and do not make a explicit call

      super(parameter,...);

      in first line of ChildClass constructor.

Compiler will add default constructor when code is compiled but when you declared a parameterized constructor in code, default constructor will be omitted.

When default constructor is overloaded with parameterized constructor, It is necessary to have a default constructor in code when you create object using default constructor instead of parameterized constructor.

There is a need of default constructor when you are using a framework (example: Spring framework) where you need to create instances of Spring bean and the bean class has only the parameterized constructor.

@Component
public class Bank {
    private String bankName;
    public Bank(String bankName){
        this.bankName = bankName;
    }
    @Override
    public String toString() {
    return this.bankName;
   }
}

public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new 
AnnotationConfigApplicationContext(SpringConfig.class);
        Bank bank = context.getBean(Bank.class);    
        System.out.println(bank);
    }
} 

will throw an error asking to implement default constructor

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM